如何利用列内换行创建MultiIndex并修复ET行缺失问题
问题:提取时区等效信息并构建MultiIndex(保留无等效时区的条目)
原始数据
import pandas as pd df = pd.DataFrame({'Abbreviation': ['ADT', 'ET', 'GMT'], 'Time zone name': ["Atlantic Daylight Time\nADST – Atlantic Daylight Saving Time\nAST – Atlantic Summer Time\nHAA – Heure Avancée de l'Atlantique (French)", 'Eastern Time', 'Greenwich Mean Time\nUTC – Coordinated Universal Time\nGT – Greenwich Time']})
预期输出
Time zone name Details Abbreviation Equivalent ADT ADST Atlantic Daylight Time Atlantic Daylight Saving Time AST Atlantic Daylight Time Atlantic Summer Time HAA Atlantic Daylight Time Heure Avancée de l'Atlantique (French) ET NaN Eastern Time NaN GMT UTC Greenwich Mean Time Coordinated Universal Time GT Greenwich Mean Time Greenwich Time
问题原因
你的代码中final = final.dropna(subset='Details')直接过滤掉了无等效时区的ET条目(它的Details为NaN),同时explode后直接concat会导致数据对齐错误,最终丢失了ET行。
修复方案
方案一:逐行处理(直观易懂)
遍历每条数据,分别处理有/无等效时区的情况,确保所有条目都被保留:
processed_rows = [] for _, row in df.iterrows(): abbr = row['Abbreviation'] time_zone_lines = row['Time zone name'].split('\n') main_zone_name = time_zone_lines[0] # 存在等效时区的情况 if len(time_zone_lines) > 1: for line in time_zone_lines[1:]: eq_abbr, details = line.split(' – ', 1) processed_rows.append({ 'Abbreviation': abbr, 'Equivalent': eq_abbr, 'Time zone name': main_zone_name, 'Details': details }) # 无等效时区的情况,填充NaN else: processed_rows.append({ 'Abbreviation': abbr, 'Equivalent': pd.NA, 'Time zone name': main_zone_name, 'Details': pd.NA }) # 转换为DataFrame并设置MultiIndex final_df = pd.DataFrame(processed_rows).set_index(['Abbreviation', 'Equivalent']) print(final_df)
方案二:向量化操作(更高效)
利用pandas向量化方法拆分、扩展数据,再合并无等效时区的条目:
# 拆分每行的时区信息,提取主时区名称 df['split_lines'] = df['Time zone name'].str.split('\n') df['Time zone name'] = df['split_lines'].str[0] # 扩展出所有等效时区条目 eq_entries = df.explode('split_lines') eq_entries = eq_entries[eq_entries['split_lines'] != eq_entries['Time zone name']] eq_entries[['Equivalent', 'Details']] = eq_entries['split_lines'].str.split(' – ', expand=True) eq_entries = eq_entries.drop(columns='split_lines') # 提取无等效时区的条目并填充NaN no_eq_entries = df[df['split_lines'].str.len() == 1].assign( Equivalent=pd.NA, Details=pd.NA ).drop(columns='split_lines') # 合并并设置索引 final_df = pd.concat([eq_entries, no_eq_entries]) final_df = final_df.sort_index(level='Abbreviation').set_index(['Abbreviation', 'Equivalent']) print(final_df)
两种方案都能生成符合预期的输出,且保留了无等效时区的ET条目。
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

