在通过 .xs 切片时在 multiIndex DataFrame 上使用 any() 和 all():奇怪的行为还是只有我?

Using any() and all() on multiIndex DataFrame while slicing via .xs: strange behavior or just me?

我对 Python 和这个社区还很陌生,所以请原谅我的业余尝试来解释我对一些很可能非常明显的事情的深刻困惑。不管怎样..

我有一个名为 "data" 的数据框。它是多索引的,有 2 个级别,包括:"date" 和 "farts"。

有一列名为:"integrated_daily_difference"。

您可以假定 "farts" 的类型为:'pandas.core.index.Index' 并且是通过以下方式创建的: farts = data.index.levels[1]

现在想象一下,我想在 farts 的任意索引值处对我的数据帧进行切片视图:即 farts[1]

我:

data.xs(farts[1], level = 1)

计算机:

                  integrated_daily_difference
        date    
2015-05-21 00:00:00+00:00    0.000000
2015-05-22 00:00:00+00:00    0.000000
2015-05-26 00:00:00+00:00   -0.024497
2015-05-27 00:00:00+00:00   -0.051144
2015-05-28 00:00:00+00:00   -0.079841
2015-05-29 00:00:00+00:00   -0.106666
2015-06-01 00:00:00+00:00   -0.131245
2015-06-02 00:00:00+00:00   -0.157428
2015-06-03 00:00:00+00:00   -0.184057
2015-06-04 00:00:00+00:00   -0.209755
2015-06-05 00:00:00+00:00   -0.234588
2015-06-08 00:00:00+00:00   -0.262365
2015-06-09 00:00:00+00:00   -0.291890
2015-06-10 00:00:00+00:00   -0.320943
2015-06-11 00:00:00+00:00   -0.352627
2015-06-12 00:00:00+00:00   -0.381425
2015-06-15 00:00:00+00:00   -0.404055

我:

data.xs(farts[1], level = 1) < 0 

计算机:

                integrated_daily_difference
         date   
2015-05-21 00:00:00+00:00   False
2015-05-22 00:00:00+00:00   False
2015-05-26 00:00:00+00:00   True
2015-05-27 00:00:00+00:00   True
2015-05-28 00:00:00+00:00   True
2015-05-29 00:00:00+00:00   True
2015-06-01 00:00:00+00:00   True
2015-06-02 00:00:00+00:00   True
2015-06-03 00:00:00+00:00   True
2015-06-04 00:00:00+00:00   True
2015-06-05 00:00:00+00:00   True
2015-06-08 00:00:00+00:00   True
2015-06-09 00:00:00+00:00   True
2015-06-10 00:00:00+00:00   True
2015-06-11 00:00:00+00:00   True
2015-06-12 00:00:00+00:00   True
2015-06-15 00:00:00+00:00   True

我假设 return我的切片数据帧中的任何位置是否存在值,所以结果为真?

我:

data.xs(farts[1], level = 1).any()

计算机:

integrated_daily_difference    True
dtype: bool

好的,这一切都有道理。现在是奇怪的东西..

我:

data.xs(farts[1], level = 1).any() < 0

计算机:

integrated_daily_difference    False
dtype: bool

咦....?

我:

data.xs(farts[1], level = 1).any(axis = 0) < 0

计算机:

integrated_daily_difference    False
dtype: bool

我:

data.xs(farts[1], level = 1).any(axis = 1) < 0

计算机:

       date
2015-05-21 00:00:00+00:00    False
2015-05-22 00:00:00+00:00    False
2015-05-26 00:00:00+00:00    False
2015-05-27 00:00:00+00:00    False
2015-05-28 00:00:00+00:00    False
2015-05-29 00:00:00+00:00    False
2015-06-01 00:00:00+00:00    False
2015-06-02 00:00:00+00:00    False
2015-06-03 00:00:00+00:00    False
2015-06-04 00:00:00+00:00    False
2015-06-05 00:00:00+00:00    False
2015-06-08 00:00:00+00:00    False
2015-06-09 00:00:00+00:00    False
2015-06-10 00:00:00+00:00    False
2015-06-11 00:00:00+00:00    False
2015-06-12 00:00:00+00:00    False
2015-06-15 00:00:00+00:00    False

我:

data.xs(farts[1], level = 1).any(axis = 1) <= 0

计算机:

        date
2015-05-21 00:00:00+00:00     True
2015-05-22 00:00:00+00:00     True
2015-05-26 00:00:00+00:00    False
2015-05-27 00:00:00+00:00    False
2015-05-28 00:00:00+00:00    False
2015-05-29 00:00:00+00:00    False
2015-06-01 00:00:00+00:00    False
2015-06-02 00:00:00+00:00    False
2015-06-03 00:00:00+00:00    False
2015-06-04 00:00:00+00:00    False
2015-06-05 00:00:00+00:00    False
2015-06-08 00:00:00+00:00    False
2015-06-09 00:00:00+00:00    False
2015-06-10 00:00:00+00:00    False
2015-06-11 00:00:00+00:00    False
2015-06-12 00:00:00+00:00    False
2015-06-15 00:00:00+00:00    False

我:

data.xs(farts[1], level = 1).any(axis = 0) <= 0

计算机:

integrated_daily_difference    False
dtype: bool

然后我的电脑开始对我狂笑,我的脑袋爆炸了...

但更严重的是,这是怎么回事?我的目标是尝试检查我的单列数据框中的所有或任何值是否满足条件和 return 布尔值 True 或 False。我似乎没有正确使用 any(),所以我正在寻求帮助。

欢迎任何意见。提前致谢!

首先让我根据 pandas-

的文档定义 any 的含义

Return whether any element is True over requested axis

现在当你写 -

data.xs(farts[1], level = 1).any()

它只是检查任何值是否为真 但是 因为没有给定条件它只会检查数字,这意味着 0 将被视为假和任何其他数字为真。现在 除了 0 之外还有 个数字,它 return 是正确的。

现在你检查 -

data.xs(farts[1], level = 1).any() < 0 

但是当表示为整数时,True 为 1,False 为 0,因此 returns False,因为 data.xs(farts[1], level = 1).any() 的输出为 True,即 1。因此,如果您检查

data.xs(farts[1], level = 1).any() == 1

它将 return 正确。

现在让我们看看当你这样做时会发生什么 -

data.xs(farts[1], level = 1).any(axis = 1) <= 0 

首先你改变了坐标轴,现在 data.xs(farts[1], level = 1).any(axis = 1) return 只是根据值(True/1 为非 0 的值和 False/0 为真和假值为 0)。现在前两个值是 0s/False 并且它满足条件 "<= 0" 它给你你看到的输出。尝试做 -

data.xs(farts[1], level = 1).any(axis = 1) == 1

你会得到刚好相反的输出。

与 any() 相反,all() 的工作方式不同... 如果全部为真或全部为假,它 return 为真,否则它只是 returns 错误。

顺便提一下-

anyoralland 是不一样的,如果你可能认为...... or 和 and 是按位运算,它们遵循 short circuit evaluation 但任何和所有函数都将遍历所有条件。

希望对您有所帮助:)

考虑这个简单的系列:

import numpy as np
np.random.seed(0)
ser = pd.Series(np.random.randint(0, 3, 10))

ser
Out[78]: 
0    0
1    1
2    0
3    1
4    1
5    2
6    0
7    2
8    0
9    0
dtype: int32

假设您要进行比较 ser < 2,它将 return 一个布尔数组:

ser < 2
Out[79]: 
0     True
1     True
2     True
3     True
4     True
5    False
6     True
7    False
8     True
9     True
dtype: bool

现在,如果你想检查它们中是否有任何一个小于 2,你需要在这个数组上调用 any

(ser < 2).any()
Out[81]: True

如果 ser < 2 数组中的至少一个值是 True,这将 return True.all() 类似:

(ser < 2).all()
Out[82]: False

由于并非所有这些都是正确的,因此 return 是错误的。如果将其更改为:

(ser < 3).all()
Out[83]: True

因为它检查 (ser < 3) 数组并且该数组中的所有元素都是 True.

现在让我们试试ser.any():

ser.any()
Out[84]: True

此处,您正在检查 原始 数组中的任何值是否为 True(如果 0 为 True,如果 1 为 True 等)。此数组中的值是整数,而不是布尔值。如果它们不等于 0,它们将被评估为 True。因此,由于该数组中至少有一个非零值,因此它 returns True.

现在,如果我检查 ser.any() < 0 它将 return False:

ser.any() < 0
Out[85]: False

这是因为这个表达式的计算结果为 True < 0:

True < 0
Out[86]: False

False,因为True不小于0,你做的类似:

data.xs(farts[1], level = 1).any() < 0

它首先在那个部分执行any(),然后returns True因为那个部分有非零元素。如果你真的想检查它们中的任何一个是否小于 0,你应该输入:

(data.xs(farts[1], level = 1) < 0).any()

(data.xs(farts[1], level = 1) < 0) 将创建一个布尔数组,如果该数组中的任何元素是 True.any() 也会 return True