2012-07-10 71 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 

对我来说,它看起来像在大熊猫的错误​​,因为{}是明确布尔值的一组有效的。