python pandas:将带有参数的函数应用于一系列


147

我想将带有参数的函数应用于python pandas中的系列:

x = my_series.apply(my_function, more_arguments_1)
y = my_series.apply(my_function, more_arguments_2)
...

文档描述了对apply方法的支持,但不接受任何参数。是否存在接受参数的其他方法?另外,我是否缺少一个简单的解决方法?

更新(2017年10月): 请注意,由于最初询问此问题以来,apply()已对熊猫进行了更新以处理位置和关键字参数,并且上面的文档链接现在反映了这一点,并说明了如何包括这两种类型的参数。


3
为什么不直接使用functools.partial,还是starmap
乔尔·科内特

Answers:


170

较新版本的pandas 确实允许您传递额外的参数(请参阅新文档)。现在,您可以执行以下操作:

my_series.apply(your_function, args=(2,3,4), extra_kw=1)

位置参数添加系列元素之后


对于旧版本的熊猫:

文档对此进行了清晰的解释。apply方法接受应具有单个参数的python函数。如果要传递更多参数,则应functools.partial按照Joel Cornett在其评论中的建议使用。

一个例子:

>>> import functools
>>> import operator
>>> add_3 = functools.partial(operator.add,3)
>>> add_3(2)
5
>>> add_3(7)
10

您也可以使用传递关键字参数partial

另一种方法是创建一个lambda:

my_series.apply((lambda x: your_func(a,b,c,d,...,x)))

但我认为使用partial会更好。


12
对于DataFrame,apply方法接受args参数,这是一个元组,其中包含其他位置参数或** kwds(用于命名参数)。我创建了一个要在Series.apply()github.com/pydata/pandas/issues/1829中
Overmeire,

28
功能已经实现,将在即将到来的大熊猫发布
韦斯·麦金尼

4
这是一个很好的答案,但是它的前2/3确实已经过时了。IMO,只需将其链接到新文档,再加上有关如何与位置和/或关键字args一起使用的简短示例,就可以很好地更新此答案。只是FWIW而不是对原始答案的批评,只会从IMO更新中受益,尤其是因为它是经常阅读的答案。
JohnE '17

@watsonic此后,文档已更新,单击旧链接会指向当前文档,该文档现在可以很好地回答该问题。
JohnE

注意:例如'abc',如果传递单个字符串参数,args=('abc')则将被评估为三个参数('a', 'b', 'c')。为避免这种情况,您必须传递一个包含字符串的元组,并为此添加一个结尾的逗号:args=('abc',)
Rocky K

82

脚步:

  1. 创建一个数据框
  2. 创建一个功能
  3. 在apply语句中使用函数的命名参数。

x=pd.DataFrame([1,2,3,4])  

def add(i1, i2):  
    return i1+i2

x.apply(add,i2=9)

此示例的结果是,数据框中的每个数字都将添加到数字9中。

    0
0  10
1  11
2  12
3  13

说明:

“添加”功能具有两个参数:i1,i2。第一个参数将是数据帧中的值,第二个参数是我们传递给“ apply”函数的值。在这种情况下,我们使用关键字参数“ i2”将“ 9”传递给apply函数。


2
正是我想要的。值得注意的是,这不需要创建自定义函数即可处理Series(或df)。完善!
康纳

剩下的唯一问题是:如何将关键字参数传递给add(i1)中的第一个arg并用i2进行迭代?
康纳

我认为这是最好的答案
crypdick

43
Series.apply(func, convert_dtype=True, args=(), **kwds)

args : tuple

x = my_series.apply(my_function, args = (arg1,))

11
谢谢!您能解释为什么第一个参数后args =(arg1,)需要逗号吗?
DrMisha 2015年

21
@MishaTeplitskiy,你需要以逗号为Python了解括号的内容是长度为1的元组
prooffreader

3
怎样给args加参数呢func?因此,如果我想申请pd.Series.mean(axis=1)该怎么办axis=1
小鲍比桌

1
附带说明,您也可以不使用<args>参数而添加关键字参数(例如:x = my_series.apply(my_function,keyword_arg = arg1),其中<keyword_arg>是my_function的输入参数之一)
lev

1
此回复太短,无法解释任何内容
FistOfFury

23

您可以将任何数量的参数传递给apply正在通过未命名参数传递,作为元组传递给args参数或通过内部由关键字捕获为字典的其他关键字参数传递给函数的kwds函数。

例如,让我们构建一个函数,该函数对于3到6之间的值返回True,否则返回False。

s = pd.Series(np.random.randint(0,10, 10))
s

0    5
1    3
2    1
3    1
4    6
5    0
6    3
7    4
8    9
9    6
dtype: int64

s.apply(lambda x: x >= 3 and x <= 6)

0     True
1     True
2    False
3    False
4     True
5    False
6     True
7     True
8    False
9     True
dtype: bool

这个匿名函数不是很灵活。让我们创建一个带有两个参数的普通函数,以控制我们在系列中所需的最小值和最大值。

def between(x, low, high):
    return x >= low and x =< high

我们可以通过将未命名的参数传递给来复制第一个函数的输出args

s.apply(between, args=(3,6))

或者我们可以使用命名参数

s.apply(between, low=3, high=6)

或两者兼而有之

s.apply(between, args=(3,), high=6)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.