如何将带有两个数组参数的函数(numpy ufunc)应用于一个pandas Series?

0 投票
1 回答
1179 浏览
提问于 2025-04-18 15:39

第二个参数应该是数组中每个元素都相同的数值。

我想从一个格式为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.applySeries.apply不需要raw这个参数。

你可能会觉得去掉raw这个参数就能解决你的问题,但Series.apply有个特别的行为:如果f是一个ufunc(通用函数),而且没有给f提供任何关键字参数,它会完全忽略args。我觉得这其实是个bug。解决办法是不要在这种情况下使用apply;因为广播规则使得在你的情况下使用apply变得多余。

撰写回答