为啥 df.apply(tuple) 有效但 df.apply(list) 无效?

Posted

技术标签:

【中文标题】为啥 df.apply(tuple) 有效但 df.apply(list) 无效?【英文标题】:Why does df.apply(tuple) work but not df.apply(list)?为什么 df.apply(tuple) 有效但 df.apply(list) 无效? 【发布时间】:2018-02-06 06:42:04 【问题描述】:

这是一个数据框:

    A  B  C
0   6  2 -5
1   2  5  2
2  10  3  1
3  -5  2  8
4   3  6  2

我可以使用df.apply 从原始df 中检索基本上是列元组的列:

out = df.apply(tuple, 1)
print(out)

0    (6, 2, -5)
1     (2, 5, 2)
2    (10, 3, 1)
3    (-5, 2, 8)
4     (3, 6, 2)
dtype: object

但如果我想要一个值列表而不是它们的元组,我不能这样做,因为它没有给我我期望的:

out = df.apply(list, 1)
print(out)

    A  B  C
0   6  2 -5
1   2  5  2
2  10  3  1
3  -5  2  8
4   3  6  2

相反,我需要这样做:

out = pd.Series(df.values.tolist())
print(out)

0    [6, 2, -5]
1     [2, 5, 2]
2    [10, 3, 1]
3    [-5, 2, 8]
4     [3, 6, 2]
dtype: object

为什么我不能使用df.apply(list, 1) 来获得我想要的东西?


附录

一些可能的解决方法的时间安排:

df_test = pd.concat([df] * 10000, 0)

%timeit pd.Series(df.values.tolist()) # original workaround
10000 loops, best of 3: 161 µs per loop

%timeit df.apply(tuple, 1).apply(list, 1) # proposed by Alexander
1000 loops, best of 3: 615 µs per loop

【问题讨论】:

奇怪的行为。 df.apply(tuple, 1).apply(list) 作为解决方法? @Alexander 可能,但速度很慢。 :( 增加了一些时间。 在你有一个列表对象的 DataFrame 时,你几乎已经放弃了对速度和效率的所有希望......注意,.apply 只是 Python 的包装器-loop,所以只需使用 iterrows 和自己的 for 循环,这可能会比 .apply 方法更快 @juanpa.arrivillaga 法定警告我知道...只是想知道为什么 pandas 与列表和元组的行为不一致。 可能是因为它并不真正意味着将它们中的任何一个作为项目一起使用,我敢打赌它会在特殊情况下列表列表像数组一样工作在处理的深处在pd.DataFrame.apply 中,但在tuples 中不这样做。但是,如果您真的关心不起作用的 .apply 的解决方法(即不使用 ufunc 开始),那么使用 iterrowsiteritems 的 for 循环是可行的方法。 .. 【参考方案1】:

罪魁祸首是here。使用func=tuple 可以工作,但使用func=list 会在编译模块lib.reduce 中引发异常:

ValueError: ('function does not reduce', 0)

如您所见,它们捕获了异常但不费心去处理它。

即使没有过于宽泛的 except 子句,这也是 pandas 中的一个错误。您可能会尝试在他们的跟踪器上提出它,但类似的问题已经通过一些不会修复或欺骗的味道来解决。

16321: weird behavior using apply() creating list based on current columns

15628: Dataframe.apply does not always return a Series when reduce=True

后一个问题在几个月前被关闭,然后重新打开,并转换为文档增强请求,现在似乎被用作任何相关问题的垃圾场。

大概这不是一个高优先级,因为作为piRSquared commented(和熊猫维护者之一commented the same),您最好使用列表理解:

pd.Series([list(x) for x in df.itertuples(index=False)])

通常apply 将使用numpy ufunc 或类似名称。

【讨论】:

非常感谢。我会研究这些链接。

以上是关于为啥 df.apply(tuple) 有效但 df.apply(list) 无效?的主要内容,如果未能解决你的问题,请参考以下文章

df.apply

df.apply 输出的新列中作为参数的特定熊猫列

Python之对DataFrame的多列数据运用apply函数操作

使用带有参数的 Pandas groupby() + apply()

规范化 pandas 中的数据

Python:数字太长怎么办? [复制]