【问题标题】:Boolean Function in pandas df column - object orientation - ambiguous truth value of a seriespandas df列中的布尔函数-面向对象-系列的模棱两可的真值
【发布时间】:2020-05-13 19:26:28
【问题描述】:

我需要一些帮助来创建一个包含布尔函数的数据框列。我想根据有关其他 df 列数据的条件接收 True 或 False 值。

数据框:

            date    C   A
0   2020-02-04  3284.75 3284.75
1   2020-02-05  3322.25 3303.50
2   2020-02-06  3333.25 3327.75
3   2020-02-07  3315.50 3324.38
4   2020-02-10  3340.25 3327.88
5   2020-02-11  3345.50 3342.88
6   2020-02-12  3367.00 3356.25
7   2020-02-13  3363.50 3365.25
8   2020-02-14  3368.25 3365.88

函数如下:

def func(C, A):
    for i in range(3):
        if C.shift(i) >= A.shift(i):
            j + 1
    if j == 3:
        val = True
    else:
        val = False
    return val

我在这里调用函数:

    data['Func'] = data.apply(func(data['C'], data['A']), axis=1)

我在这个例子中遇到的错误是

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

我试图让它工作的最常见错误是

TypeError: 'DatetimeIndex' object is not callable

AttributeError: ("'numpy.float64' object has no attribute 'shift'",

此时我不确定哪些元素有效或无效。任何帮助,将不胜感激。提前致谢。

【问题讨论】:

  • 该函数试图确定何时存在“C”值大于“A”值的一系列连续三行。

标签: python pandas dataframe object boolean


【解决方案1】:
  • Row-wise .apply 就像一个美化的for-loop,这意味着你的函数中的CA 都等于一个值,而不是一个系列。因此shift 将不起作用。
  • 你可以试试np.where
  • 预期的输出并不完全清楚,因此希望这能让您走上正轨。
import numpy as np

df['Func'] = np.where((df.C.shift(0) >= df.A.shift(0)) & (df.C.shift(1) >= df.A.shift(1)) & (df.C.shift(2) >= df.A.shift(2)), True, False)

display(df)

       C        A   Func
 3284.75  3284.75  False
 3322.25  3303.50  False
 3333.25  3327.75   True
 3315.50  3324.38  False
 3340.25  3327.88  False
 3345.50  3342.88  False
 3367.00  3356.25   True
 3363.50  3365.25  False
 3368.25  3365.88  False

说明

  • 对于每一行,每个条件必须为TrueFuncTrue

shift(0)

df.C.shift(0) >= df.A.shift(0)

date
2020-02-04     True
2020-02-05     True
2020-02-06     True
2020-02-07    False
2020-02-10     True
2020-02-11     True
2020-02-12     True
2020-02-13    False
2020-02-14     True

shift(1)

df.C.shift(1) >= df.A.shift(1)

date
2020-02-04    False
2020-02-05     True
2020-02-06     True
2020-02-07     True
2020-02-10    False
2020-02-11     True
2020-02-12     True
2020-02-13     True
2020-02-14    False

shift(2)

df.C.shift(2) >= df.A.shift(2)

date
2020-02-04    False
2020-02-05    False
2020-02-06     True
2020-02-07     True
2020-02-10     True
2020-02-11    False
2020-02-12     True
2020-02-13     True
2020-02-14     True

【讨论】:

  • 感谢 Trenton McKinney 的详尽回答。这段代码确实有效。会说这种方法是“矢量化的”吗?我现在正在研究这个话题。这个函数的真正目的有不止三行回顾,并且将在大型数据集上执行,所以我想改进这个计算以尽可能高效地执行。可能这本身就是一个问题。任何见解都会有所帮助。
  • @Ludlow_Luddite 是的,我的理解是这种布尔切片是矢量化的。很高兴它有效。 .apply 就像一个高效的for-loop
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 2019-05-18
  • 2015-09-14
  • 2022-09-28
  • 1970-01-01
  • 2017-09-23
相关资源
最近更新 更多