Python Pandas,应用功能

时间:2017-04-18 19:53:20

标签: python pandas

我正在尝试使用apply来避免函数中的iterrows()迭代器:

然而,pandas方法的文档记录很少,我找不到如何使用它的示例,除了文档中的跛脚.apply(sq.rt) ...没有关于如何使用参数等的示例... < / p>

无论如何,这是我试图做的一个玩具示例。

在我的理解中,apply实际上将与iterrows()相同,即迭代(如果axis = 0,则遍历行)。在每次迭代时,函数的输入x应该是迭代的行。然而,我一直接受的错误消息反驳了这种假设......

grid = np.random.rand(5,2)
df = pd.DataFrame(grid)

def multiply(x):
    x[3]=x[0]*x[1]

df = df.apply(multiply, axis=0)

上面的示例返回一个空的df。任何人都可以对我的误解有所了解吗?

4 个答案:

答案 0 :(得分:3)

import pandas as pd
import numpy as np

grid = np.random.rand(5,2)
df = pd.DataFrame(grid)

def multiply(x):
    return x[0]*x[1]

df['multiply'] = df.apply(multiply, axis = 1)
print(df)

结果:

          0         1  multiply
0  0.550750  0.713054  0.392715
1  0.061949  0.661614  0.040987
2  0.472134  0.783479  0.369907
3  0.827371  0.277591  0.229670
4  0.961102  0.137510  0.132162

说明:

apply的功能需要返回一个值。您也将此应用于每一行,而不是列。在这方面,您传递的axis参数不正确。

最后,请注意我将其设置为与我的函数之外的'multiply'列相同。您可以轻松地将此更改为df[3] = ...,并获得如下数据框:

          0         1         3
0  0.550750  0.713054  0.392715
1  0.061949  0.661614  0.040987
2  0.472134  0.783479  0.369907
3  0.827371  0.277591  0.229670
4  0.961102  0.137510  0.132162

答案 1 :(得分:1)

apply一个函数时,您需要该函数来在列/行上返回该操作的结果。您收到None因为multiply没有返回,显然。也就是说,apply应该在特定值之间返回结果,而不是自己进行赋值。

你也在这里迭代错误的轴。您当前的代码采用每个列的第一个和第二个元素并将它们相乘。

正确的multiply功能:

def multiply(x):
    return x[0]*x[1]

df[3] = df.apply(multiply, 'columns')

据说,你可以在这里做得比apply好得多,因为它不是矢量化操作。只需将列直接相乘即可。

df[3] = df[0]*df[1]

一般情况下,你应尽可能避免apply,因为它不仅仅是一个循环本身。

答案 2 :(得分:1)

Pandas Zen的一条规则是:always try to find a vectorized solution first

.apply(..., axis=1)没有矢量化!

考虑替代方案:

In [164]: df.prod(axis=1)
Out[164]:
0    0.770675
1    0.539782
2    0.318027
3    0.597172
4    0.211643
dtype: float64

In [165]: df[0] * df[1]
Out[165]:
0    0.770675
1    0.539782
2    0.318027
3    0.597172
4    0.211643
dtype: float64

针对50.000行的时间DF:

In [166]: df = pd.concat([df] * 10**4, ignore_index=True)

In [167]: df.shape
Out[167]: (50000, 2)

In [168]: %timeit df.apply(multiply, axis=1)
1 loop, best of 3: 6.12 s per loop

In [169]: %timeit df.prod(axis=1)
100 loops, best of 3: 6.23 ms per loop

In [170]: def multiply_vect(x1, x2):
     ...:     return x1*x2
     ...:

In [171]: %timeit multiply_vect(df[0], df[1])
1000 loops, best of 3: 604 µs per loop

结论:使用.apply()作为最后的手段(即没有别的帮助)

答案 3 :(得分:0)

应该注意,您也可以使用lambda函数。查看他们的文档Apply

对于您的示例,您可以运行

df['multiply'] = df.apply(lambda row: row[0] * row[1], axis = 1)

产生与@Andy相同的输出

如果你的功能是

的形式,这可能很有用
def multiply(a,b):
    return a*b

df['multiply'] = df.apply(lambda row: multiply(row[0] ,row[1]), axis = 1)

Enhancing Performance

部分中的更多示例