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

Abe*_*Abe 114 python apply pandas

我想在python pandas中为一个系列应用带参数的函数:

x = my_series.apply(my_function, more_arguments_1)
y = my_series.apply(my_function, more_arguments_2)
...
Run Code Online (Sandbox Code Playgroud)

文档描述了对apply方法的支持,但它不接受任何参数.是否有接受参数的不同方法?或者,我错过了一个简单的解决方法吗?

更新(2017年10月): 请注意,由于此问题最初被要求apply()已更新pandas 以处理位置和关键字参数,上面的文档链接现在反映了这一点并显示了如何包含任一类型的参数.

Bak*_*riu 135

文档清楚地解释了这一点.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
Run Code Online (Sandbox Code Playgroud)

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

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

my_series.apply((lambda x: your_func(a,b,c,d,...,x)))
Run Code Online (Sandbox Code Playgroud)

但我认为使用partial更好.


需要注意的是熊猫的新版本允许你通过额外的参数(见新的文档).所以现在你可以这样做:

my_series.apply(your_function, args=(2,3,4), extra_kw=1)
Run Code Online (Sandbox Code Playgroud)

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

  • 功能已经实现,将在即将发布的熊猫版本中发布 (28认同)
  • 对于DataFrame,apply方法接受`args`参数,该参数是一个元组,包含额外的位置参数或**kwds用于命名的参数.我也为Series.apply()创建了一个问题https://github.com/pydata/pandas/issues/1829 (12认同)
  • 这是一个很好的答案,但是它的前2/3确实已经过时了。IMO,这个答案可以很好地更新,只需将其链接到新文档,再加上一个简短的示例来说明如何使用位置和/或关键字args。只是FWIW而不是对原始答案的批评,只会从IMO更新中受益,尤其是因为它是经常阅读的答案。 (4认同)
  • 注意:如果您传递单个字符串参数,例如 `'abc'`,则 `args=('abc')` 将被评估为三个参数 `('a', 'b', 'c')` 。为了避免这种情况,您必须传递一个包含字符串的元组,为此,请包含一个尾随逗号:`args=('abc',)` (2认同)

Fis*_*ury 63

脚步:

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

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

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

x.apply(add,i2=9)
Run Code Online (Sandbox Code Playgroud)

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

    0
0  10
1  11
2  12
3  13
Run Code Online (Sandbox Code Playgroud)

说明:

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

  • 正是我要找的。值得注意的是,这不需要创建自定义函数来处理系列(或 df)。完美的! (2认同)
  • 唯一剩下的问题是:如何将关键字参数传递给 add (i1) 中的第一个参数并使用 i2 进行迭代? (2认同)

小智 41

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

args : tuple

x = my_series.apply(my_function, args = (arg1,))
Run Code Online (Sandbox Code Playgroud)

  • @MishaTeplitskiy,你需要逗号才能让Python理解括号的内容是长度为1的元组. (20认同)
  • 谢谢!你能解释为什么args =(arg1,)在第一个参数后需要一个逗号吗? (10认同)
  • 怎么样为`func`放入args呢?因此,如果我想应用`pd.Series.mean(axis = 1)`,我该如何放入`axis = 1`? (2认同)

Ted*_*rou 18

您可以将任意数量的参数传递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
Run Code Online (Sandbox Code Playgroud)

这个匿名函数不是很灵活.让我们创建一个带有两个参数的普通函数来控制我们在系列中想要的最小值和最大值.

def between(x, low, high):
    return x >= low and x =< high
Run Code Online (Sandbox Code Playgroud)

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

s.apply(between, args=(3,6))
Run Code Online (Sandbox Code Playgroud)

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

s.apply(between, low=3, high=6)
Run Code Online (Sandbox Code Playgroud)

甚至两者兼而有之

s.apply(between, args=(3,), high=6)
Run Code Online (Sandbox Code Playgroud)