*编辑编辑*
我花了相当长的时间来解决这个问题,尽管普通的普通案例很好用,但我在混合类型的DataFrame上仍然遇到此错误。
我的目标是添加两个新的计算列。
import pandas as pd
import datetime as dt
df = pd.DataFrame({'one' : pd.Series([1, 2, 3, 4]),
'two' : pd.Series([20, 30, 40, 50]),
'zree': pd.Series([dt.datetime(2016, 7, x) for x in range(1, 5)])})
df['sum'], df['prod'] = zip(*df.apply(lambda row: (row.one + row.two,
row.one * row.two), axis=1))
...
ValueError: Shape of passed values is (4, 2), indices imply (4, 3)
当我删除包含datetime的列'zree'或将类型更改为int时,错误消失。
有什么解决方法吗?
任何帮助将不胜感激。
import sys
print(sys.version)
3.5.1 |Anaconda 4.0.0 (64-bit)| (default, Feb 16 2016, 09:49:46) [MSC v.1900 64 bit (AMD64)]
pd.__version__
'0.18.1'
您对混合类型的问题很感兴趣,并在DataFrame
的源代码中做了一些挖掘。显然,当你DataFrame
是混合类型(即df._is_mixed_type
是True
),不同的功能比当它是均匀的施加。
当您调用apply
混合类型的DataFrame时,它将调用DataFrame._apply_standard
(至少在您的情况下),然后返回DataFrame(data=results, index=index)
。results
是从函数的输出构建的字典,{0: (21, 20), 1: (32, 60), 2: (43, 120), 3: (54, 200)}
并且index
是Index(['one', 'two', 'zree'])
(即的列DataFrame
)。如您所见,索引的大小(3)与结果的大小(每列2个)之间存在差异,这是不匹配的。
为避免这种情况,您需要Series
在函数中返回a :
df.apply(lambda row: pd.Series((row.one + row.two, row.one * row.two)), axis=1)
在这种情况下,结果DataFrame
中将使用df的索引,而不是将列用作索引:
In [83] df.apply(lambda row: pd.Series((row.one + row.two, row.one * row.two)), axis=1)
Out[83]
0 1
0 21 20
1 32 60
2 43 120
3 54 200
要从您的原始帖子中获得理想的结果,您可以执行以下操作:
In [90] zip(*df.apply(lambda row: pd.Series((row.one + row.two,
row.one * row.two)), axis=1).values)
Out[90] [(21, 32, 43, 54), (20, 60, 120, 200)]
在相同类型的情况下,由于函数的输出是列表(一维)DataFrame
,DataFrame._apply_raw
因此调用时返回a Series
。
我希望这可以解决问题,如果需要更多信息,可以进行一些调试。我使用0.18.1版的熊猫进行了测试。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句