如何在Pandas中合并特定列含多级数据的行
解决方案
针对重复行合并的需求,这里提供两种高效处理方式,同时解决groupby时特殊列名报错的问题:
方法一:添加类型标记后重塑数据
先从现有列提取每行属于Coolest还是Warmest的标记,再通过pivot实现行合并:
import pandas as pd # 读取数据并清理含Ties的行 df = pd.read_html('https://www.ncei.noaa.gov/access/monitoring/climate-at-a-glance/statewide/rankings/1/tavg/202302')[0] df = df.loc[~df.Value.str.contains('Ties')] # 添加类型标记列:从Rank列提取Coolest/Warmest df['Type'] = df['Rank(1895-2023)'].str.extract(r'(Coolest|Warmest)') # 重塑数据,合并相同Period的行 result = df.pivot( index='Period', columns='Type', values=['Rank(1895-2023)', 'Warmest/CoolestSince', 'Record'] ).swaplevel(0, 1, axis=1).sort_index(axis=1) # 扁平化列名(可选,让列名更直观) result.columns = [f'{col[0]}_{col[1]}' for col in result.columns] # 保留基础列并合并 base_cols = df[['Period', 'Value', '1901-2000Mean', 'Anomaly']].drop_duplicates().set_index('Period') final_df = base_cols.join(result).reset_index() print(final_df)
方法二:使用groupby聚合处理
针对groupby特殊列名报错的问题,只需将带特殊字符的列名用引号包裹或放入列表即可避免语法错误,以下是聚合实现:
import pandas as pd # 读取并清理数据 df = pd.read_html('https://www.ncei.noaa.gov/access/monitoring/climate-at-a-glance/statewide/rankings/1/tavg/202302')[0] df = df.loc[~df.Value.str.contains('Ties')] # 添加类型标记 df['Type'] = df['Rank(1895-2023)'].str.extract(r'(Coolest|Warmest)') # 定义聚合规则:基础列取第一个值,其余列按Type转为字典 agg_rules = { 'Value': 'first', '1901-2000Mean': 'first', 'Anomaly': 'first', 'Rank(1895-2023)': lambda x: dict(zip(df.loc[x.index, 'Type'], x)), 'Warmest/CoolestSince': lambda x: dict(zip(df.loc[x.index, 'Type'], x)), 'Record': lambda x: dict(zip(df.loc[x.index, 'Type'], x)) } # 按Period分组聚合 grouped = df.groupby(['Period']).agg(agg_rules) # 展开字典列到单独列 for col in ['Rank(1895-2023)', 'Warmest/CoolestSince', 'Record']: grouped = grouped.join(pd.DataFrame(grouped[col].tolist(), index=grouped.index).add_prefix(f'{col}_')) grouped.drop(col, axis=1, inplace=True) # 重置索引 final_df = grouped.reset_index() print(final_df)
关键问题说明
关于你遇到的SyntaxError: positional argument follows keyword argument:
当列名包含括号、斜杠等特殊字符时,不能直接作为关键字参数传递。解决办法:
- 将列名放在列表中传递给
groupby,比如df.groupby(['Period']) - 聚合时用字典格式指定规则,避免直接使用带特殊字符的列名作为参数名
两种方法最终都会得到目标格式:每个Period对应一行,新增Rank(1895-2023)_Coolest、Rank(1895-2023)_Warmest等列分别存储对应数据。
内容的提问来源于stack exchange,提问作者bismo
相关产品推荐
相关产品推荐

