我正在尝试使用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。任何人都可以对我的误解有所了解吗?
答案 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)
部分中的更多示例