2 回答

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超4個(gè)贊
已經(jīng)解釋了為什么您對(duì) NA 列的比較沒有返回您期望的結(jié)果。
但是,我會(huì)以與他不同的方式進(jìn)行比較。這是一個(gè)小片段,應(yīng)該可以幫助您理解:
# a series of bools, indicating for which index our condition is true
na_gt_1_series = df["NA"] > 1
print(na_gt_1)
# creating a new column based on the values of the NA column
df["na_gt_1"] = na_gt_1_series
print(df)
現(xiàn)在,由于這里的條件相當(dāng)復(fù)雜,我認(rèn)為使用 pandas 的 apply 函數(shù)會(huì)更簡(jiǎn)單,它沿著 DataFrame 的某個(gè)軸應(yīng)用一個(gè)函數(shù)。
def get_row_df5(row):
df5 = 0
if row["NA"] > 1:
if row["MULT"] == 1:
if row["NOB"] == 1:
df5 = -A1 * row["NOB"]
else:
df5 = -A2 * row["NOB"] - B * (row["NOA"] - row["NOB"])
elif row["NA"] == 1:
if row["MULT"] == 1:
if row["EX"] == 0 and row["NOB"] == 4 and row["CHARGE"] == 0:
df5 = -A1 * row["NOB"]
elif row["NOB"] != 1 or row["NOB"] == 1 and row["EX"] != 0:
df5 = -C * row["NOB"]
elif row["NOB"] == 1 and row["EX"] == 0:
df5 = -E * row["NOB"]
else:
df5 = -C * row["NOB"] - D * (row["NOA"] - row["NOB"])
return df5
df5_res = df.apply(func=get_row_df5, axis=1)
不幸的是,這種簡(jiǎn)單性是有代價(jià)的。對(duì)于通過復(fù)制示例數(shù)據(jù)制作的 120,000 行 DataFrame,應(yīng)用解決方案需要約 4 秒,而以下解決方案需要約 40 毫秒(快 100 倍)。
def get_df5_broad(df_in):
na_lt_1 = df_in["NA"] > 1
na_eq_1 = df_in["NA"] == 1
mult_eq_1 = df_in["MULT"] == 1
mult_ne_1 = ~mult_eq_1
res_series = pd.Series(np.zeros(shape=df_in.shape[0]))
res_series.loc[na_lt_1 & mult_eq_1 & (df_in["NOB"] == 1)] = -A1 * df_in["NOB"]
res_series.loc[na_lt_1 & mult_ne_1] = -A2 * df_in["NOB"] - B * (df_in["NOA"] - df_in["NOB"])
res_series.loc[na_eq_1 & mult_eq_1 & (df_in["EX"] == 0) & (df_in["NOB"] == 4) & (df_in["CHARGE"] == 0)] = -A1 * df_in["NOB"]
res_series.loc[na_eq_1 & mult_eq_1 & ((df_in["NOB"] != 1) | ((df_in["NOB"] == 1) & (df_in["EX"] != 0)))] = -C * df_in["NOB"]
res_series.loc[na_eq_1 & mult_eq_1 & (df_in["NOB"] == 1) & (df_in["EX"] == 0)] = -E * df_in["NOB"]
res_series.loc[na_eq_1 & mult_ne_1] = -C * df_in["NOB"] - D * (df_in["NOA"] - df_in["NOB"])
return res_series
最后,下一個(gè)方法是兩全其美的方法。它的設(shè)計(jì)和簡(jiǎn)單性與使用 apply 的方法相似,但僅比之前的高性能版本慢 5 倍。
def get_df5_tupe(tupe):
df5 = 0
if tupe.NA > 1:
if tupe.MULT == 1:
if tupe.NOB == 1:
df5 = -A1 * tupe.NOB
else:
df5 = -A2 * tupe.NOB - B * (tupe.NOA - tupe.NOB)
elif tupe.NA == 1:
if tupe.MULT == 1:
if tupe.EX == 0 and tupe.NOB == 4 and tupe.CHARGE == 0:
df5 = -A1 * tupe.NOB
elif tupe.NOB != 1 or tupe.NOB == 1 and tupe.EX != 0:
df5 = -C * tupe.NOB
elif tupe.NOB == 1 and tupe.EX == 0:
df5 = -E * tupe.NOB
else:
df5 = -C * tupe.NOB - D * (tupe.NOA - tupe.NOB)
return df5
def get_df5_iter(df_in):
return pd.Series((get_df5_tupe(curr) for curr in df_in.itertuples(index=False)))
注意:由于 OP 中的邏輯歧義,這些方法并不總是返回正確的答案。一旦正確的布爾表達(dá)式可用,我將立即編輯我的解決方案。

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超5個(gè)贊
這個(gè)塊在這里:
if (df['NA'] > 1).any():
print(True)
elif (df['NA'] == 1).any():
print(False)
將始終打印 True 因?yàn)榱?'NA' 的值大于 1,因此不會(huì)評(píng)估第二個(gè) elif。根據(jù)您的評(píng)論,如果我沒記錯(cuò)的話,我認(rèn)為您想遍歷 DataFrame 并評(píng)估每個(gè)元素。你可以嘗試這樣的事情:
for val in df['NA']:
if val > 1:
print(True)
elif val == 1:
print(False)
這將評(píng)估列“NA”的每個(gè)元素,對(duì)于您的實(shí)際用例,您將想知道給定 val 的索引,這可以使用enumerate. 例如:
for (idx, val) in enumerate(df['NA']):
if val > 1:
d5 = -A1 * df['NOB'].iloc[idx]
elif val == 1:
d5 = E * df['NOB'].iloc[idx]
idx是當(dāng)前元素的索引,您可以使用 訪問該索引處其他列的元素iloc。我希望這會(huì)有所幫助,祝你好運(yùn)。
添加回答
舉報(bào)