Python pandas,.apply,使用多个返回值

时间:2018-01-22 14:12:23

标签: python pandas

<script src="/AdBlock/src/com/example/myproject/client/Flipper.java"></script> 

somefunc:
- 从url中的json获取带有参数input1和input2的数据并将其放入   新数据框df2
- 使用df2的值创建output1,output2 - 在计算输出变量以节省RAM时删除数据帧

这完全执行,但我想返回3个返回错误的值

in[1]:  

import pandas as pd

    def somefunc(input1, input2):
        output1 = 1
        output2 = 2

        return [output1, output2]


d = {'col1': ['A1', 'B1'], 'col2': ['A2', 'B2']}
df = pd.DataFrame(data=d)

df[['col3', 'col4']] = df.apply(lambda x: somefunc(x['col1'], x['col2']), 
axis=1)

print df  

out[1]:  

   col1 col2  col3  col4
0   A1   A2     1     2
1   B1   B2     1     2

错误与我的实际程序有所不同,但我猜它与之相关;

in[2]:  

import pandas as pd

    def somefunc(input1, input2):
        output1 = 1
        output2 = 2  
        output3 = 3


        return [output1, output2, output3]


d = {'col1': ['A1', 'B1'], 'col2': ['A2', 'B2']}
df = pd.DataFrame(data=d)

df[['col3', 'col4', 'col5']] = df.apply(lambda x: somefunc(x['col1'], x['col2']), 
axis=1)

print df  

out[2]:  
"ValueError: Columns must be same length as key"

为什么这适用于一个和两个输出而不是三个?
Python 2.7.14

2 个答案:

答案 0 :(得分:1)

解决方案是从自定义函数返回Series

def somefunc(input1, input2):
    output1 = 1
    output2 = 2  
    output3 = 3

    return pd.Series([output1, output2, output3])

d = {'col1': ['A1', 'B1'], 'col2': ['A2', 'B2']}
df = pd.DataFrame(data=d)

df[['col3', 'col4', 'col5']] = df.apply(lambda x: somefunc(x['col1'], x['col2']), axis=1)
print (df)
  col1 col2  col3  col4  col5
0   A1   A2     1     2     3
1   B1   B2     1     2     3

或者通过构造函数从DataFrame创建list

def somefunc(input1, input2):
    output1 = 1
    output2 = 2  
    output3 = 3

    return [output1, output2, output3]

d = {'col1': ['A1', 'B1'], 'col2': ['A2', 'B2']}
df = pd.DataFrame(data=d)

df1 = df.apply(lambda x: somefunc(x['col1'], x['col2']), axis=1)
df[['col3', 'col4', 'col5']] = pd.DataFrame(df1.values.tolist())
print (df)
  col1 col2  col3  col4  col5
0   A1   A2     1     2     3
1   B1   B2     1     2     3

答案 1 :(得分:1)

您偶然发现了数据框与结果之间的形状不匹配

如果您要注意,在第一种情况下,您有一个2列的数据框,并且您的结果将作为两个项目的列表返回。你会看到中间输出是这样的:

   col1  col2
0     1     2
1     1     2

pandas做了什么,是它有特殊的返回值,并且快照到与输入相同大小的数据框中(它假设你想要一个数据帧,因为结果的形状是相同的)。由于在这种情况下结果是DataFrame,您可以将其分配回来。

遗憾的是,对于第二个函数,列表中返回的元素数是 3 。这 not 与原始数据框的大小相同,因此返回的是单个列列表。

0    [1, 2, 3]
1    [1, 2, 3]
dtype: object

Pandas不知道如何处理这些数据,因此不会对此做任何事情。巧合的是,您无法将列表的Series对象分配给数据帧切片,因此您会收到错误。

这里的解决方案是返回一个列表,而是返回一个pd.Series对象。

def somefunc(input1, input2):
    return pd.Series([1, 2, 3])

这会返回一个数据帧(pandas现在巧妙地堆叠每个系列以在最终数据帧中形成一行):

   0  1  2
0  1  2  3
1  1  2  3

分配这个就像以前一样容易。