【问题标题】:Pandas apply ValueError: The truth value of a Series is ambigousPandas 应用 ValueError:Series 的真值不明确
【发布时间】:2018-07-05 17:26:41
【问题描述】:

我正在尝试使用

创建一个新功能
df_transactions['emome'] = df_transactions['emome'].apply(lambda x: 1 if df_transactions['plan_list_price'] ==0 & df_transactions['actual_amount_paid'] > 0 else 0).astype(int)

但它会引发错误

ValueError:Series 的真值不明确。使用 a.empty, a.bool()、a.item()、a.any() 或 a.all()。

当 plan_list_price 为 0 且 actual_amount_paid 为 >0 时,我如何创建一个返回 1 的新列,否则为 0?

我仍想使用 pandas 申请。

【问题讨论】:

  • "我还想使用 pandas apply。"为什么?
  • 因为我之前遇到过几次这个问题,我想学习使用pandas apply的正确方法。
  • 正确的使用 apply... 的方法是根本不使用它;)另外,原因是你使用了 & 当你应该使用 and。不要互换使用它们。 & 仅在数据帧上下文中为逻辑 AND。
  • 问题本身并不适用。这是您对如何使用多个逻辑条件的误解,其中存在重复。
  • 我试过了,还是一样的错误

标签: python pandas


【解决方案1】:

您真的很接近,但没有apply 的矢量化解决方案要好得多 - 获取布尔掩码并转换为int

mask = (df_transactions['plan_list_price'] == 0) & 
       (df_transactions['actual_amount_paid'] > 0)
df_transactions['emome'] = mask.astype(int)

如果真的想慢点apply:

f = lambda x: 1 if x['plan_list_price'] ==0 and x['actual_amount_paid'] > 0 else 0
df_transactions['emome'] = df_transactions.apply(f, axis=1)

示例:

df_transactions = pd.DataFrame({'A':list('abcdef'),
                                'plan_list_price':[0,0,0,5,5,0],
                                'actual_amount_paid':[-1,0,9,4,2,3]})


mask = (df_transactions['plan_list_price'] == 0) & \
       (df_transactions['actual_amount_paid'] > 0)
df_transactions['emome1'] = mask.astype(int)

f = lambda x: 1 if x['plan_list_price'] ==0 and x['actual_amount_paid'] > 0 else 0
df_transactions['emome2'] = df_transactions.apply(f, axis=1)
print (df_transactions)

   A  actual_amount_paid  plan_list_price  emome1  emome2
0  a                  -1                0       0       0
1  b                   0                0       0       0
2  c                   9                0       1       1
3  d                   4                5       0       0
4  e                   2                5       0       0
5  f                   3                0       1       1

时间安排

#[60000 rows]
df_transactions = pd.concat([df_transactions] * 10000, ignore_index=True)

In [201]: %timeit df_transactions['emome1'] = ((df_transactions['plan_list_price'] == 0) & (df_transactions['actual_amount_paid'] > 0)).astype(int)
1000 loops, best of 3: 971 µs per loop

In [202]: %timeit df_transactions['emome2'] = df_transactions.apply(lambda x: 1 if x['plan_list_price'] ==0 and x['actual_amount_paid'] > 0 else 0, axis=1)
1 loop, best of 3: 1.15 s per loop

【讨论】:

  • 我想用df_transactions['emome'] = df_transactions['emome'].apply(xxx),xxx部分怎么填?
【解决方案2】:

几个问题:

  • 在等式的右侧,新字段 (emome) 不是 尚未创建。
  • lambda 函数在 x 上,而不是在 df_transactions 上,它在此范围内不存在。
  • 您需要指定轴,因为您要应用于每一行(默认为每一列)。

来自文档:

axis : {0 or ‘index’, 1 or ‘columns’},默认为 0 应用函数:

0 或“索引”:将函数应用于每一列。 1 或“列”:应用 每一行的函数。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html

【讨论】:

    猜你喜欢
    • 2021-09-10
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2021-09-01
    • 2019-10-29
    • 2018-06-14
    • 2016-12-01
    相关资源
    最近更新 更多