<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
答案 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
分配这个就像以前一样容易。