在一个空的pandas DataFrame上调用apply()函数

21

我遇到了关于Pandas数据框的apply()方法的问题。我的问题是apply()方法根据输入函数的返回类型可以返回Series或DataFrame,但当数据框为空时,apply()方法(几乎)总是返回一个DataFrame。因此我不能写期望返回Series的代码。以下是一个例子:

import pandas as pd

def area_from_row(row):
    return row['width'] * row['height']

def add_area_column(frame):
    # I know I can multiply the columns directly, but my actual function is
    # more complicated.
    frame['area'] = frame.apply(area_from_row, axis=1)

# This works as expected.
non_empty_frame = pd.DataFrame(data=[[2, 3]], columns=['width', 'height'])
add_area_column(non_empty_frame)

# This fails!
empty_frame = pd.DataFrame(data=None, columns=['width', 'height'])
add_area_column(empty_frame)

有没有一种标准的方法来处理这个问题?我可以按照以下方式操作,但这很傻:

def area_from_row(row):
    # The way we respond to an empty row tells pandas whether we're a
    # reduction or not.
    if not len(row):
        return None
    return row['width'] * row['height']

我正在使用pandas 0.11.0,但我还在0.12.0-1100-g0c30665上检查了一下。


如果DataFrame为空,不调用add_area_column怎么样?(例如,将ifadd_area_column中移除,并将其放在您调用apply的位置) - Matt
@Matt,是的,那样做可以行得通,但每次我想以这种方式添加列时都必须添加此检查。(或者我可以为apply()定义自己的包装器。)虽然比我问题中的解决方法更好,但我希望有一种更优雅的方法。 - traversable
这些 apply 的边缘情况非常棘手... 要解决您的问题,请不要使用 apply:df['width'] * df['height'] - Andy Hayden
1个回答

28
你可以在 apply 函数中设置 result_type 参数为 'reduce'。
根据文档,如果 result_type=None,则最终返回类型将从应用函数的返回类型推断。否则,它取决于 result_type 参数。
然后,“reduce” :如果可能的话返回一个 Series,而不是扩展类似列表的结果。这与“expand”相反。
在你的代码中进行更新:
def add_area_column(frame):
    # I know I can multiply the columns directly, but my actual function is
    # more complicated.
    frame['area'] = frame.apply(area_from_row, axis=1, result_type='reduce')

4
我意识到这个回答是在六年后发布的,但也许会对一些路过的人有所帮助。 - Ian

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