我想使用Pandas在資料框中創建一個新列,在該列中比較 df 中一行中的 2 列,如果值不同,則選擇特定列,如果值相等,則選擇其中任何一個,如果一個其中在 NaN 中,選擇另一個(如果兩者都是 NaN,它將已經被覆寫)。我正在使用Numpy select和Pandas where,但無法使其作業,而且我不想(還)使用for回圈。
如果我得到這個資料框:
df1 = pd.DataFrame([["A", "B"], ["C", "D"], [np.nan, "A"], ["B", np.nan], [np.nan, np.nan], ["E", "E"]], columns=["col1", "col2"])
df1
col1 col2
0 A B
1 C D
2 NaN A
3 B NaN
4 NaN NaN
5 E E
我希望行為是這樣的:
- 在第 0 行,因為 (A != B) & (A != np.nan) & (B != np.nan) 我想從 col1 中選擇值。
- 在第 1 行,因為 (C != D) & (C != np.nan) & (D != np.nan) 我想從 col1 中選擇值(與以前相同)。
- 在第 2 行,因為 (NaN != A) & (A != np.nan) & (NaN == np.nan) 我想從 col 2 中選擇值。
- 在第 3 行,因為 (B != NaN) & (NaN == np.nan) & (B != np.nan) 我想從 col 1 中選擇值。
- 在第 4 行,因為 (NaN == NaN) & (NaN == np.nan) & (NaN == np.nan) 我想從 col1 中選擇值(兩者都可以實際作業)。
- 在第 5 行,因為 (E == E) & (E != np.nan) & (E != np.nan) 我想選擇 col 1 的值形式(與以前相同)。
在這種情況下,我應該獲得類似的東西:
col1 col2 col3
0 A B A
1 C D C
2 NaN A A
3 B NaN B
4 NaN NaN NaN
5 E E E
為了實作這一點,我這樣做了np.select:
df1 = pd.DataFrame([["A", "B"], ["C", "D"], [np.nan, "A"], ["B", np.nan], [np.nan, np.nan], ["E", "E"]], columns=["col1", "col2"])
conditions = [
((df['col1'] == df['col2']) & (df['col1'] != np.nan)),
((df['col1'] == df['col2']) & (df['col1'] == np.nan)),
((df['col1'] != df['col2']) & (df['col1'] != np.nan) & (df['col2'] == np.nan)),
((df['col1'] != df['col2']) & (df['col1'] == np.nan) & (df['col2'] != np.nan)),
]
choices = [df['col1'], np.nan, df['col1'], df['col2']]
df['condition'] = np.select(conditions, choices, default="WHAT?")
print(df)
但結果是:
col1 col2 condition
0 A B WHAT?
1 C D WHAT?
2 NaN A WHAT?
3 B NaN WHAT?
4 NaN NaN WHAT?
5 E E E
所以,我不明白我做錯了什么。
半編輯:在寫這篇文章時,我注意到我在選擇中缺少一個案例,所以我將代碼更新為:
希望有人可以幫助我,謝謝
df1 = pd.DataFrame([["A", "B"], ["C", "D"], [np.nan, "A"], ["B", np.nan], [np.nan, np.nan], ["E", "E"]], columns=["col1", "col2"])
conditions = [
((df['col1'] == df['col2']) & (df['col1'] != np.nan)),
((df['col1'] == df['col2']) & (df['col1'] == np.nan)),
((df['col1'] != df['col2']) & (df['col1'] != np.nan) & (df['col2'] == np.nan)),
((df['col1'] != df['col2']) & (df['col1'] == np.nan) & (df['col2'] != np.nan)),
((df['col1'] != df['col2']) & (df['col1'] != np.nan) & (df['col2'] != np.nan)),
]
choices = [df['col1'], np.nan, df['col1'], df['col2'], df["col1"]]
df['condition'] = np.select(conditions, choices, default="WHAT?")
print(df)
結果是這樣的:
col1 col2 condition
0 A B A
1 C D C
2 NaN A NaN
3 B NaN B
4 NaN NaN NaN
5 E E E
為了進一步說明,我將選擇更改為:[1, 2, 3, 4, 5]。這是結果:
col1 col2 condition
0 A B 5
1 C D 5
2 NaN A 5
3 B NaN 5
4 NaN NaN 5
5 E E 1
它總是在第五種情況下進入,對于第0行和第1行是可以的,但是第2行應該進入第4種情況,第3行應該進入第3種情況,第4行應該進入第2種情況。第5行對第1種情況是正確的。
希望我說清楚了,謝謝。
編輯:有人評論然后洗掉對我有用的東西。這個人指出,如果你這樣做:print(np.nan == np.nan)它會回傳False,所以我的邏輯總是會失敗。因此,我必須在條件句中使用notnull()和。isna()
uj5u.com熱心網友回復:
np.nan != np.nanNaN 永遠不會彼此相等,因此您的邏輯沒有按照您的想法進行:df['col1'] != np.nan. 嘗試做print(np.nan == np.nan),它總是會回傳 False。您想使用df['col1'].isna()來查找空值和df['col1'].notnull()查找非空值。
conditions = [
((df['col1'] == df['col2']) & (df['col1'].notnull())),
((df['col1'] == df['col2']) & (df['col1'].isna())),
((df['col1'] != df['col2']) & (df['col1'].notnull()) & (df['col2'].isna())),
((df['col1'] != df['col2']) & (df['col1'].isna()) & (df['col2'].notnull())),
((df['col1'] != df['col2']) & (df.notnull().all(1))),# not sure if this is the logic you actually want
]
choices = [df['col1'], np.nan, df['col1'], df['col2'], df["col1"]]
df['condition'] = np.select(conditions, choices, default="WHAT?")
col1 col2 condition
0 A B A
1 C D C
2 NaN A A
3 B NaN B
4 NaN NaN WHAT?
5 E E E
uj5u.com熱心網友回復:
這是您的問題的另一種解決方案:
df1 = pd.DataFrame([["A", "B"], ["C", "D"], [np.nan, "A"], ["B", np.nan], [np.nan, np.nan], ["E", "E"]], columns=["col1", "col2"])
col3 = []
for i, row in df1.notna().iterrows():
if row.all():
col3.append(df1['col1'].iloc[i])
elif row.values[0]:
col3.append(df1['col1'].iloc[i])
else:
col3.append(df1['col2'].iloc[i])
df1['col3'] = col3
print(df1)
輸出:
col1 col2 col3
0 A B A
1 C D C
2 NaN A A
3 B NaN B
4 NaN NaN NaN
5 E E E
uj5u.com熱心網友回復:
這將是我個人使用的那個。這是使用串列理解的非常簡潔的答案。
import pandas as pd
import numpy as np
df1 = pd.DataFrame([["A", "B"], ["C", "D"], [np.nan, "A"], ["B", np.nan], [np.nan, np.nan], ["E", "E"]], columns=["col1", "col2"])
df1['col3'] = [row[0] if row[0] is not np.nan else row[1] for i, row in df1.iterrows()]
print(df1)
輸出:
col1 col2 col3
0 A B A
1 C D C
2 NaN A A
3 B NaN B
4 NaN NaN NaN
5 E E E
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/524758.html
上一篇:按天對大df中的值求和并鍵入
