当通过apply函数传递pandas列时,数据类型会变为对象吗?

16

我需要在一个函数中使用 pandas 列的 dtype,但是当我使用 apply 调用该函数时,dtype 出现了变化,变成了 object。有人知道这是怎么回事吗?

import pandas as pd

df = pd.DataFrame({'stringcol':['a'], 'floatcol': [1.5]})
df.dtypes
Out[1]: 
floatcol     float64
stringcol     object
dtype: object

df.apply(lambda col: col.dtype)
Out[2]: 
floatcol     object
stringcol    object
dtype: object

请注意,如果直接传递列,则不会出现此问题:

f = lambda col: col.dtype
f(test.floatcol)
Out[3]: dtype('float64')
2个回答

14

这似乎是由于DataFrame._apply_standard中的优化导致的。该方法代码中的“快速路径”创建了一个输出Series,其数据类型为df.values的数据类型,而在您的情况下,由于DataFrame是混合类型,因此数据类型为object。如果您在apply调用中传递参数reduce=False,则结果是正确的:

>>> df.apply(lambda col: col.dtype, reduce=False)
floatcol     float64
stringcol     object
dtype: object

我必须说,对于reduce的这种行为与文档的一致性,我并不清楚。


不错,我似乎记得 DataFrame.to_sql 存在类似的 bug... 我想知道这种“优化”作为默认行为是否有问题,因为我使用的每个 dataframe 几乎都有混合数据类型... - maxymoo
似乎不适用于 pandas 1.3.4,我得到了 TypeError: <lambda>() got an unexpected keyword argument 'reduce' - Rishabh Agrahari
@RishabhAgrahari:看起来apply已经更改了,现在它有一个result_type参数,而不是reduce。但是它似乎也被更改了,所以问题所问的问题不再存在(即,仅使用常规apply不再强制将列转换为对象dtype)。 - BrenBarn

1
对于pandas版本v0.23+,答案是:

>>> df.apply(lambda x: x.dtype, result_type='expand')

即使 Pandas 文档声称 result_type 参数 "仅在 axis=1 (列) 时起作用",但这仍然有效。

感谢 @jezrael


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接