将函数应用于一对Pandas系列。

3
假设我有两个系列:
s = pd.Series([20, 21, 12]
t = pd.Series([17,19 , 11]

我希望将一个两个参数的函数应用到这两个系列上,以得到一系列结果(作为一系列输出)。现在,实现该功能的一种方法如下:
df = pd.concat([s, t], axis=1)
result = df.apply(lambda x: foo(x[s], x[t]), axis=1)

但是这种方法似乎有些笨重。是否有更加优雅的方式呢?


你确定 lambda x: foo(x[s], x[t]) 是正确的吗?难道你的意思不是对每个 st 值的每一行应用 foo 函数吗?那么 foo 函数是什么样子的呢? - Rodalm
@Rodalm 这有什么关系呢?这是一个接受两个参数的函数。是的,我只想逐行应用foo。 - Igor Rivin
因为它不能按照所需方式工作,并使您的解决方案变得不必要地复杂。您只需要编写 result = df.apply(foo, axis=1),这样会使您的解决方案更加优雅。或者如果您想要 result = pd.concat([s, t], axis=1).apply(foo, axis=1) - Rodalm
4个回答

4

有很多方法可以实现您想要的功能。

根据具体的函数,您可能可以直接将其应用于系列。例如,调用s + t会返回

0    37
1    40
2    23
dtype: int64

然而,如果你的函数比简单的算术更复杂,你可能需要做些创新。一个选项是使用内置的Python map 函数。例如,调用

list(map(np.add, s, t))

返回

[37, 40, 23]


1
如果两个序列具有相同的索引,您可以使用列表推导式创建一个序列:
result = pd.Series([foo(xs, xt) for xs,xt in zip(s,t)], index=s.index)

如果无法保证两个系列具有相同的索引,则使用concat是最好的选择,因为它可以帮助对齐索引。

这确实是一个不错的解决方案,但我没有想到它,因为似乎遍历列表会产生很多开销。我错了吗? - Igor Rivin
2
是的,你错了 :-). apply 也会创建一个等价于列表的对象,还会增加一些索引对齐的开销。 - Quang Hoang

1

如果我理解正确,您可以使用此方法来应用一个函数,使用两列数据,并将结果复制到另一列中:

df['result'] = df.loc[:, ['s', 't']].apply(foo, axis=1)

1

可以尝试使用numpy.vectorize

from numpy import vectorize

vect_foo = vectorize(foo)
result = vect_foo(s, t)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接