Pandas使用groupby检测字符串列值变化且忽略分组首行的实现方法
解决方法
直接在比较逻辑后补充fillna(False)处理分组首行的缺失值比较结果,再转整型即可,不需要额外操作分组首行索引,修改后的代码如下:
import pandas as pd # 生成测试数据 case = pd.Series(['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C']) val1 = pd.Series(['Cat1', 'Cat1', 'Cat1', 'Cat1', 'Cat1', 'Cat2', 'Cat2', 'Cat1', 'Cat2', 'Cat1', 'Cat1', 'Cat2']) expectation = pd.Series([0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1]) df = pd.DataFrame({'case': case, 'val1': val1, 'expectation' : expectation}) # 修正后的逻辑 df['my_test'] = (df.groupby('case')['val1'].shift() != df['val1']).fillna(False).astype(int) # 验证结果 print(df)
原逻辑问题说明
原有代码的问题在于:分组后每个组的第一行调用shift(1)返回的是缺失值,缺失值与任意值做不等于比较都会返回True,所以首行会被错误标记为1。上面的修正逻辑里,直接把这部分缺失值对应的比较结果填充为False,转整型后自然就是0,完全匹配预期输出。
运行后输出结果如下,my_test与expectation列完全一致:
case val1 expectation my_test 0 A Cat1 0 0 1 A Cat1 0 0 2 A Cat1 0 0 3 A Cat1 0 0 4 B Cat1 0 0 5 B Cat2 1 1 6 B Cat2 0 0 7 B Cat1 1 1 8 C Cat2 0 0 9 C Cat1 1 1 10 C Cat1 0 0 11 C Cat2 1 1
内容的提问来源于stack exchange,提问作者John Stud
相关产品推荐
相关产品推荐

