2012-07-10 104 views
47

我想通過每行的函數來過濾行,例如,pandas:DataFrame的行上的複雜過濾器

def f(row): 
    return sin(row['velocity'])/np.prod(['masses']) > 5 

df = pandas.DataFrame(...) 
filtered = df[apply_to_all_rows(df, f)] 

還是其他更復雜的,人爲的例子,

def g(row): 
    if row['col1'].method1() == 1: 
    val = row['col1'].method2()/row['col1'].method3(row['col3'], row['col4']) 
    else: 
    val = row['col2'].method5(row['col6']) 
    return np.sin(val) 

df = pandas.DataFrame(...) 
filtered = df[apply_to_all_rows(df, g)] 

我怎麼可以這樣做?

回答

70

您可以使用DataFrame.apply這樣做,whic^h應用一個函數沿着給定軸,

In [3]: df = pandas.DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c']) 

In [4]: df 
Out[4]: 
      a   b   c 
0 -0.001968 -1.877945 -1.515674 
1 -0.540628 0.793913 -0.983315 
2 -1.313574 1.946410 0.826350 
3 0.015763 -0.267860 -2.228350 
4 0.563111 1.195459 0.343168 

In [6]: df[df.apply(lambda x: x['b'] > x['c'], axis=1)] 
Out[6]: 
      a   b   c 
1 -0.540628 0.793913 -0.983315 
2 -1.313574 1.946410 0.826350 
3 0.015763 -0.267860 -2.228350 
4 0.563111 1.195459 0.343168 
+1

在這種情況下沒有必要申請。一個普通的布爾索引可以正常工作。 'df [df ['b]> df ['c']]'。有很少的情況實際上需要'應用',甚至很少有需要'axis = 1'的情況 – 2017-11-06 17:28:48

8

假設我有一個數據幀如下:

In [39]: df 
Out[39]: 
     mass1  mass2 velocity 
0 1.461711 -0.404452 0.722502 
1 -2.169377 1.131037 0.232047 
2 0.009450 -0.868753 0.598470 
3 0.602463 0.299249 0.474564 
4 -0.675339 -0.816702 0.799289 

我可以用罪和DataFrame.prod創建一個布爾面膜:

In [40]: mask = (np.sin(df.velocity)/df.ix[:, 0:2].prod(axis=1)) > 0 

In [41]: mask 
Out[41]: 
0 False 
1 False 
2 False 
3  True 
4  True 

然後使用面膜從數據框中選擇:

In [42]: df[mask] 
Out[42]: 
     mass1  mass2 velocity 
3 0.602463 0.299249 0.474564 
4 -0.675339 -0.816702 0.799289 
+2

其實,這可能是一個壞榜樣:'np.sin'自動廣播到所有元素。如果我用一個只能處理一個輸入的智能較少的函數來替換它,該怎麼辦? – duckworthd 2012-07-10 21:07:50

1

我canot上duckworthd's answer發表評論,但它不是完美的工作。它崩潰時數據框爲空:

df = pandas.DataFrame(columns=['a', 'b', 'c']) 
df[df.apply(lambda x: x['b'] > x['c'], axis=1)] 

輸出:

ValueError: Must pass DataFrame with boolean values only 

對我來說,它看起來像在大熊貓的錯誤​​,因爲{}是明確布爾值的一組有效的。