Pandas - 在每列上应用一个返回多个值的函数

时间:2018-02-07 19:46:27

标签: python pandas dataframe apply

我有一个数据框

>>>df = pd.DataFrame({"a" : [1,2,3], "b" :[4,5,6], "c":[10,11,12]})
   a  b   c
0  1  4  10
1  2  5  11
2  3  6  12

和一个返回多个值的函数。

>>>def my_fun(values):
>>>    return(values+10, values*3)

它适用于单个列:

>>>res_1, res_2 = my_fun(df['a'])
>>>print(res_1)

0    3
1    6
2    9

>>>print(res_2)

0    11
1    12
2    13

但是当我尝试使用apply来获取两个数据帧时,我收到错误。

>>>res_1, res_2 = df.apply(my_fun, axis=0)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-173-142501cd22f6> in <module>()
     23 #     return(values_2+10, values_2*3)
     24 
---> 25 res_1, res_2 = df.apply(my_fun, axis=0)

ValueError: too many values to unpack (expected 2)

有任何线索吗?请注意,这只是一个示例性的例子。

更新

我的目标是按列方式应用函数而不是其他解决方法(因为这个例子只是一个例子)。上面提供的示例含糊不清,下面会有更好的示例,我想在其中添加每列的平均值:

>>>import numpy as np
>>>def my_fun_2(values):
>>>    return(values+np.mean(values), values*3)

2 个答案:

答案 0 :(得分:4)

好像你只需要像这样调用func

df1,df2=my_fun(df)
df1
Out[1455]: 
    a   b   c
0  11  14  20
1  12  15  21
2  13  16  22
df2
Out[1456]: 
   a   b   c
0  3  12  30
1  6  15  33
2  9  18  36

您的函数当前返回值的方式不适合与apply一起使用。

答案 1 :(得分:1)

关键问题是你的函数正在返回一个tuple对象,res_1, res_2 = my_fun(df['a'])正在做的是将返回的元组res_1res_2解压缩为{{1}对象。

举例说明:

Series

如果您愿意,可以 手动将这些内容解压缩到df.apply(my_fun) # a ([11, 12, 13], [3, 6, 9]) # b ([14, 15, 16], [12, 15, 18]) # c ([20, 21, 22], [30, 33, 36]) # dtype: object df.applymap(my_fun) # a b c # 0 (11, 3) (14, 12) (20, 30) # 1 (12, 6) (15, 15) (21, 33) # 2 (13, 9) (16, 18) (22, 36) DataFrame,但您可以看到它很繁琐:

apply

因此,除非您想要更改函数以返回不同的对象类型或手动将它们解压缩到两个不同的df1 = df.apply(my_fun, axis = 0).apply(lambda x: x[0]).transpose() df2 = df.apply(my_fun, axis = 0).apply(lambda x: x[1]).transpose() df1 # a b c # 0 11 14 20 # 1 12 15 21 # 2 13 16 22 df2 # a b c # 0 3 12 30 # 1 6 15 33 # 2 9 18 36 对象中,@ Wen的解决方案对您来说是最好和最简单的。