第一:也許這適合代碼審查更好,但我認爲這裏是更多熊貓仿射用戶。隨意移動它,如果你認爲否則根據其他列創建新列:DRY並啓用功能
這是常有的情況下,一個要計算一個新列了現有的: 考慮以下大熊貓據幀
df = pd.DataFrame({'ItemNumber':np.arange(1, 10),
'A':[1,1,1,2,2,2,3,3,3], 'B': [1,2,3]*3})
print(df)
A B ItemNumber
0 1 1 1
1 1 2 2
2 1 3 3
3 2 1 4
4 2 2 5
5 2 3 6
6 3 1 7
7 3 2 8
8 3 3 9
比方說,我們計算通過
df.loc[(df["A"] == 1) & (df["B"] > 1), 'C'] = 1
df.loc[(df["B"] == 1) & (df["A"] > 1), 'C'] = 2
df.loc[(df["A"] > 1) & (df["B"] > 1), 'C' ] = 3
df.loc[(df["A"] == 1) & (df["B"] == 1), 'C' ] = 4
新列「C」這會相比,迭代的方法,在大型dataframes執行相當快也呈現here。 特別是,該方法的性能問題使我得到了上述代碼。
但是,這段代碼違反了DRY原則。複製粘貼感覺很尷尬。
所以,讓我們多一點的功能和定義兩個咖喱功能:
def col_equals_value(col, value):
def filter_df(df):
return df[col] == value
return filter_df
def col_greater_value(col, value):
def filter_df(df):
return df[col] > value
return filter_df
從那裏,我們定義的比較:需要
a1 = col_equals_value('A', 1)
b1 = col_equals_value('B', 1)
agt1 = col_greater_value('A', 1)
bgt1 = col_greater_value('B', 1)
另一個函數的值賦給列:
def assign_value(cond_1, cond_2, value):
def assign_col_value(df, col):
df.loc[df.apply(cond_1, axis=1) & df.apply(cond_2, axis=1), col] =value
return assign_col_value
最後,我們可以定義condtion-to-values mappin G作爲
mapping = [(a1, b1, 4),
(a1, bgt1, 1),
(agt1, b1, 2),
(agt1, bgt1, 3)]
構建assign_value_functions
m = [assign_value(x, y, z) for (x,y,z) in mapping]
和各功能適用於數據框:
for f in m:
f(df, 'C')
print(df)
A B ItemNumber
0 1 1 1
1 1 2 2
2 1 3 3
3 2 1 4
4 2 2 5
5 2 3 6
6 3 1 7
7 3 2 8
8 3 3 9
那麼什麼是問題? 這種方法似乎不是非常可擴展的。對於每個比較運算符,我似乎都需要定義一個全新的函數。比較運算符是一個變量嗎? 目前,我只支持2個條件與&運營商連接。如何推廣? 我不確定如何調用apply方法。我覺得應該有一個更簡單的方法。
歡迎任何幫助
嘿,我真的很喜歡你的想法,它很簡單,映射的定義比較精確。但是,我還不確定我是否在尋找更多功能的解決方案。我想,我的解決方案可以通過使用運算符模塊和reduce函數來改進,以允許任意多個條件。但映射/轉換可能不太可讀。 – Quickbeam2k1