如何将带有两个数组参数的函数(numpy ufunc)应用于一个pandas Series?
第二个参数应该是数组中每个元素都相同的数值。
我想从一个格式为YYYYMMMDD的数字代码中提取出月份和日期。我会对每个值使用numpy.mod(datenum,10000)
,但是numpy的模运算需要两个类似数组的参数。
根据pandas.apply的说明,我尝试了以下测试代码,但没有成功:
import numpy as np
from pandas import *
s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
t = s.apply(np.mod,raw=True,args=(10000,))
print s
print t
Traceback (most recent call last):
File "…", line 7, in <module>
t = s.apply(np.mod,raw=True,args=(10000,))
File "…/miniconda/lib/python2.7/site-packages/pandas/core/series.py", line 2023, in apply
mapped = lib.map_infer(values, f, convert=convert_dtype)
File "inference.pyx", line 920, in pandas.lib.map_infer (pandas/lib.c:44780)
File "…/miniconda/lib/python2.7/site-packages/pandas/core/series.py", line 2012, in <lambda>
f = lambda x: func(x, *args, **kwds)
TypeError: 'raw' is an invalid keyword to ufunc 'remainder'
如果不加raw=True
,错误信息是:
Traceback (most recent call last):
File "…", line 7, in <module>
t = s.apply(np.mod,args=(10000,))
File "…/miniconda/lib/python2.7/site-packages/pandas/core/series.py", line 2017, in apply
return f(self)
ValueError: invalid number of arguments
这个是怎么回事呢?
1 个回答
4
由于广播规则,10000看起来像一个数组,你可以直接把它传给mod
或者%
,就像它真的是一个数组一样:
In [13]: s
Out[13]:
a 85626286
b 66577463
c 75552690
d 36817240
e 75994944
dtype: int64
In [14]: s % 10000
Out[14]:
a 6286
b 7463
c 2690
d 7240
e 4944
dtype: int64
至于apply
,你看错文档了。你在查看Dataframe.apply
的内容,但你其实是在处理一个序列,所以应该查看Series.apply
。Series.apply
不需要raw
这个参数。
你可能会觉得去掉raw
这个参数就能解决你的问题,但Series.apply
有个特别的行为:如果f
是一个ufunc(通用函数),而且没有给f
提供任何关键字参数,它会完全忽略args
。我觉得这其实是个bug。解决办法是不要在这种情况下使用apply
;因为广播规则使得在你的情况下使用apply
变得多余。