为什么 pandas 在 `apply` 中处理这两个字符串时会有不同的结果?

3

我不明白为什么pandas会区别对待两个lambda函数 l3l4 - 它们都只接受一个参数、返回一个字符串,而且都不应该被执行,因为df实际上是空的:

import pandas as pd

df = pd.DataFrame(data={"col1": [], "col2": []})

l3 = lambda r: ""
l4 = lambda r: f"{r.col1}"

df["col3"] = df.apply(l3, axis=1)
df["col4"] = df.apply(l4, axis=1)  # Error: Wrong number of items passed 3, placement implies 1

print(type(df.apply(l3, axis=1)))  # this is a Series
print(type(df.apply(l4, axis=1)))  # this is a DataFrame

然而,df.apply的返回类型是不同的。

奖励问题:是否有更好的做法?

df["col4"] = df.apply(l4, axis=1)

这适用于空数据帧的解决方案是什么?
更新:我认为pandas代码的一个相关部分是这个:
在这个部分中,根据@mozway的回答,该函数应用于一个空序列,并基于是否可行返回生成的新序列或输入的副本(即数据框)。
根据@Brandt的评论,可能应该确保该函数也适用于空行(这是一个奇怪的、至少未记录的要求)。 https://github.com/pandas-dev/pandas/blob/8e07787bc1030e5d13d3ad5e83b5d060a519ef67/pandas/core/apply.py#L718-L753

1
关于您的奖励问题:l4 = lambda r: f"{r.col1}" if len(r) else "" 应该可以解决。 - Brandt
另外,当我运行您的代码(使用我上面建议的l4)时,在两种情况下(print/type),我都得到了Series。我正在使用Pandas v1.3.1。 - Brandt
1个回答

3
你应该添加result_type='reduce'参数以避免扩展到DataFrame:
df = pd.DataFrame(data={"col1": [], "col2": []})

l3 = lambda r: ""
l4 = lambda r: f"{r.col1}"

df["col3"] = df.apply(l3, axis=1)
df["col4"] = df.apply(l4, axis=1, result_type='reduce')

1
请注意,df.apply在两种情况下都可以工作。不起作用的是分配给新列。 - bers
@bers 好的,我明白了,这是一个result_type的问题,请查看编辑 - mozway
但是你仍然是正确的:“当没有行时,apply将一个空的Series传递给函数。”这只是在try/catch块中发生,所以我们看不到它失败 - 请参见我的更新问题。 - bers

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