关于pandas .cumsum()的费解行为:布尔序列累加为何分段计数?
搞懂
(sign != sign.shift()).cumsum()的分组魔法 哈哈,这个操作看起来有点绕,但其实是利用了pandas的两个小特性组合出来的分组神器,我给你一步步拆解:
第一步:
sign.shift()的偏移作用
它会把整个sign序列往下挪一位,第一个位置会变成NaN(毕竟没有前一个元素能移过来嘛)。比如你的sign如果是[+1, +1, -1, -1, +1, ...],偏移后就变成[NaN, +1, +1, -1, +1, ...]。第二步:
sign != sign.shift()的布尔判断
这一步是逐个对比原序列和偏移后序列的元素:- 第一个元素和
NaN比,结果是True(因为NaN和任何值都不相等,包括它自己); - 后面的元素只要和前一个元素不一样,就返回
True,一样就返回False。
重点来了:pandas里布尔值会自动转成数值——True等价于1,False等价于0,这是后续累加的关键。
- 第一个元素和
第三步:
.cumsum()的累加逻辑
累加就是把前面所有的数值依次加起来:- 遇到1(也就是前后元素发生变化时),总和就加1;
- 遇到0(前后元素保持相同时),总和就维持当前数值不变。
这么一来,累加的结果就相当于给每一组连续相同的元素分配了一个专属编号——每次元素切换时编号涨1,同一组里的编号就一直固定,这就是你看到的输出效果啦!
举个对应你输出的小例子:假设你的sign序列是[+1, +1, -1, -1, +1, -1, +1, -1, +1, -1, +1, -1],那sign != sign.shift()的结果就是[True, False, True, False, True, True, True, True, True, True, True, True],转成1和0累加后,就正好是你给出的输出序列。
这个技巧在处理连续相同元素的分组问题时超级实用,很多时序数据的分组场景都会用到它~
内容的提问来源于stack exchange,提问作者user3556757
相关产品推荐
相关产品推荐

