使用zip()在混合类型的数据帧上抛出“传递值的形状是(x,y),索引意味着(w,z)”

2024-05-16 22:43:28 发布

您现在位置:Python中文网/ 问答频道 /正文

*编辑编辑编辑*

我在这个问题上纠结了一段时间,虽然普通的示例可以正常工作,但在混合类型的数据帧上,我总是遇到这个错误。在

我的目标是添加两个新的计算列。在

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'或将type更改为int时,错误就会消失。在

有什么解决办法吗?在

任何帮助将不胜感激。在

^{pr2}$

Tags: import编辑示例类型dfdatetimeas错误
2条回答

显然df.apply也需要为第三列返回一些内容,而您的lambda为每一行返回两个值。 因此,只需像这样选择前两列,为您的apply获取一个4x2数据帧:

df['sum'], df['prod'] = zip(*df[['one', 'two']].apply(lambda row: (row.one + row.two, row.one * row.two), axis=1))

我对您的混合类型问题很感兴趣,并深入研究了DataFrame的源代码。显然,当你的DataFrame是混合类型(即df._is_mixed_type是{})时,应用的函数与同构时不同。在

当您对混合类型的数据帧调用apply时,它调用DataFrame._apply_standard(至少在您的例子中是这样),然后返回DataFrame(data=results, index=index)results是根据函数{0: (21, 20), 1: (32, 60), 2: (43, 120), 3: (54, 200)}的输出生成的dict,index是{}(即,DataFrame的列)。如您所见,索引(3)的大小与结果(每列2个)的大小不匹配。在

要避免这种情况,需要在函数中返回Series

df.apply(lambda row: pd.Series((row.one + row.two, row.one * row.two)), axis=1)

在本例中,df的索引用于结果DataFrame,而不是作为索引的列:

^{pr2}$

要从原始帖子中获得所需的结果,可以执行以下操作:

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被调用,在您的例子中,它返回一个Series,因为函数的输出是一个列表(一维)。在

我希望这能把事情弄清楚一点,如果需要了解更多信息,可以进行一些调试。我用熊猫0.18.1版进行了测试。在

相关问题 更多 >