Pandas Series.ne运算符针对同一系列的两个切片返回意外结果

时间:2018-02-22 19:45:18

标签: python pandas series

所以我有下面显示的这一系列整数

from pandas import Series
s = Series([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

我想知道数字在系列中的变化次数,因此我可以执行以下操作并获得预期结果。

[i != s[:-1][idx] for idx, i in enumerate(s[1:])]
Out[5]: 
[True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 True,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False,
 False]

从那里我可以简单地计算真实的数量。但这显然不是操作熊猫系列的最佳方式,而且我在性能很重要的情况下添加它,所以我做了以下预期相同的结果,但是我非常惊讶和困惑。

s[1:].ne(s[:-1])
Out[4]: 
0      True
1     False
2     False
3     False
4     False
5     False
6     False
7     False
8     False
9     False
10    False
11    False
12    False
13    False
14    False
15    False
16    False
17    False
18    False
19    False
20    False
21    False
22    False
23    False
24    False
25    False
26    False
27    False
28    False
29    False
30    False
31    False
32    False
33    False
34    False
35    False
36    False
37    False
38    False
39     True
dtype: bool

使用Series.ne方法的输出不仅对我没有任何逻辑意义,而且输出也比任何一个特别令人困惑的输入都长。

我认为这可能与此https://github.com/pandas-dev/pandas/issues/1134

有关

无论我对自己做错了什么以及实现这一目标的最佳方式感到好奇。

TL; DR:

其中s是pandas.Series of int'

[i != s[:-1][idx] for idx, i in enumerate(s[1:])] != s[:-1].ne(s[1:]).tolist()

修改 谢谢大家,阅读以下一些可能解决方案的答案是sum(s.diff().astype(bool)) - 1但是我仍然很好奇为什么上述解决方案无法正常工作

3 个答案:

答案 0 :(得分:1)

IIUC,使用shift

s!=s.shift()

答案 1 :(得分:1)

您可以使用diff

s.diff().ne(0)

答案 2 :(得分:1)

您可以利用diff

>>> from pandas import Series
>>> s = Series([1, 2, 1, 3, 3, 1, 1])
>>> s.diff()
0    NaN
1    1.0
2   -1.0
3    2.0
4    0.0
5   -2.0
6    0.0
dtype: float64
>>> s.diff().ne(0) # Same of s.diff() != 0
0     True
1     True
2     True
3     True
4    False
5     True
6    False
dtype: bool
>>> # To know how many times the values had changed simply count the
... # number of True, except the first which is fault of the NaN
... # generated by `diff()` function.
...
>>> sum(s.diff().ne(0)) - 1
4