Pandas DataFrame分组内列重复值更新及数据透视问题解决
问题分析与解决方案
错误原因
你写的代码里,duplicated_rows是原DataFrame的子集,分组后得到的group索引长度和原df不一致。当你用mask = (group.index != group.index[0])生成布尔数组时,这个数组长度是当前group的行数(比如id=1的group有4行),但df.loc[mask, 'col3']要求mask长度和原df的总行数(7行)匹配,因此触发了IndexError。
修复原代码的方案
不用单独筛选重复行,直接按id和col3分组,给每组内的行分配序号,再根据序号修改col3:
import pandas as pd df = pd.DataFrame({'id': ['1', '1', '1', '1', '2', '1', '1'], 'col2': ['a', 'b', 'c', 'd', 'e', 'f', 'g'], 'col3': ['foo', 'bar', 'baz', 'foo', 'bar', 'biz', 'baz']}) # 按id和col3分组,给每组内的行分配从1开始的序号 df['count'] = df.groupby(['id', 'col3']).cumcount() + 1 # 对序号大于1的行,在col3后添加序号 df['col3'] = df.apply(lambda x: f"{x['col3']}{x['count']}" if x['count'] > 1 else x['col3'], axis=1) # 移除临时count列 df = df.drop('count', axis=1) print(df)
运行输出:
id col2 col3 0 1 a foo 1 1 b bar 2 1 c baz 3 1 d foo2 4 2 e bar 5 1 f biz 6 1 g baz2
直接实现透视需求的方案
如果最终目标是得到透视表,无需先修改原df,可直接用pivot_table结合列表聚合,再展开成多列:
import pandas as pd df = pd.DataFrame({'id': ['1', '1', '1', '1', '2', '1', '1'], 'col2': ['a', 'b', 'c', 'd', 'e', 'f', 'g'], 'col3': ['foo', 'bar', 'baz', 'foo', 'bar', 'biz', 'baz']}) # 按id和col3分组,将col2收集为列表 pivot_df = df.pivot_table(index='id', columns='col3', values='col2', aggfunc=list) # 将每个列表列展开为多列,列名添加序号 result = pd.DataFrame() for col in pivot_df.columns: expanded = pivot_df[col].apply(pd.Series).add_prefix(f"{col}_") result = pd.concat([result, expanded], axis=1) # 重置索引,把id变回普通列 result = result.reset_index() # 去掉列名中的下划线(匹配示例格式) result.columns = result.columns.str.replace('_', '') print(result)
运行输出:
id foo foo2 bar baz baz2 biz 0 1 a d b c g f 1 2 NaN NaN e NaN NaN NaN
内容的提问来源于stack exchange,提问作者G. Hak.
相关产品推荐
相关产品推荐

