【问题标题】:lamba function with if else带有 if else 的 lambda 函数
【发布时间】:2018-08-10 15:30:24
【问题描述】:

我有一个如下所示的数据框:

A   B   C   D   SUM 
2   5   -4  12  15

我尝试运行:

df.apply((lambda x: x / x.sum() if x/x.sum() >= 0 else None), axis=1).fillna(0)

如果单元格总数相同,则计算 x/total:

A         B     C   D
2/15    5/15    0   12/15

我明白了:

'The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

如何改进代码。

【问题讨论】:

  • x/x.sum() 应该返回什么?
  • 为什么不只检查一个数字是否为负数? x/x.sum() 只会在 x < 0x.sum() < 0 时为负数?你甚至不需要lambda 函数。您可以将 Dataframe 中的所有负值替换为 None,并将总和小于 0 的行设置为 None
  • x/x.sum() 是:单元格中的值除以一行中所有单元格中的值之和。
  • 这不是if/elselambda 的问题,而是应该如何将一系列值视为布尔值。
  • “如果单元格总数相同”是什么意思?

标签: python pandas if-statement dataframe lambda


【解决方案1】:

您混淆了pd.Series.applypd.DataFrame.apply。它们是不同的方法:一种是在一个系列上工作,对每个元素进行操作;另一个沿轴跨数据框运行。在后一种情况下,沿axis=1 表示每个 都按顺序提供给函数。

因为这些 apply 方法(两个版本)只是隐蔽的循环,所以数据框将在每次按列调用 lambda 后发生变化。因此,您需要使用数据框的副本:

df2 = df.copy()

for col in df.columns[:-1]:
    df2[col] = df.iloc[:, :-1].apply(lambda x: x[col] / x.sum() if x[col]/x.sum() >= 0 \
                                     else None, axis=1).fillna(0)

print(df2)

          A         B  C    D  SUM
0  0.133333  0.333333  0  0.8   15

但是,这一切都非常低效。我们没有使用底层的 NumPy 数组。相反,您可以使用矢量化操作:

res = df.iloc[:, :-1].div(df.iloc[:, :-1].sum(1), axis=0)
res.mask(res < 0, 0, inplace=True)

print(res)

          A         B    C    D
0  0.133333  0.333333  0.0  0.8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多