如何为Pandas DataFrame筛选行生成递增序列号并优化代码?
Pandas生成分组序列号问题解决
问题
我用Pandas DataFrame的apply()函数生成serialno列,但输出不符合预期。当前仅在col1≠col2的行显示起始值4,其余行显示0;预期要求col1≠col2时序列号从4开始递增,且同一col1组内的所有行重复该序列号。需要修改代码实现预期输出,同时用向量操作替代apply()提升效率。
当前输出
col1 col2 serialno 0 100 0 4 1 100 100 0 2 100 100 0 3 200 100 4 4 200 200 0 5 300 200 4 6 300 300 0
预期输出
col1 col2 serialno 0 100 0 4 1 100 100 4 2 100 100 4 3 200 100 5 4 200 200 5 5 300 200 6 6 300 300 6
现有代码
import pandas as pd columns = ['col1'] data = ['100','100','100','200','200','300','300'] df = pd.DataFrame(data=data,columns=columns) df['col2'] = df.col1.shift(1).fillna(0) print(df) start = 4 series = (df['col1']!=df['col2']).apply(lambda x: start if x==True else 0) df['serialno'] = series print(df)
解决方案
实现思路
- 通过
col1 != col2识别分组变化的边界,生成布尔序列 - 对布尔序列做累加(
cumsum()),得到每个新分组的递增序号(从1开始) - 加上起始值的偏移量(
start - 1),让序号从指定的起始值4开始 - 累加操作会让同一
col1组内的所有行保持相同序号,无需额外填充即可满足需求
修改后的代码
import pandas as pd columns = ['col1'] data = ['100','100','100','200','200','300','300'] df = pd.DataFrame(data=data, columns=columns) df['col2'] = df.col1.shift(1).fillna(0) start = 4 # 生成分组递增序号并偏移到起始值 df['serialno'] = (df['col1'] != df['col2']).cumsum() + (start - 1) print(df)
代码说明
(df['col1'] != df['col2']).cumsum():将分组变化的布尔值转换为累加序号,第一个分组为1,第二个为2,以此类推+ (start - 1):把累加序号的起始点从1调整为4,最终得到4、5、6的分组序号- 全程使用Pandas内置向量操作,比
apply()的逐行处理效率高得多,尤其适合大数据集
内容的提问来源于stack exchange,提问作者plain
相关产品推荐
相关产品推荐

