多列含相同分隔符的DataFrame行拆分及值复制问题
问题解决:按分号拆分DataFrame行并保留无分隔符列的原值
需求:遍历DataFrame每一行,若某列值包含分号“;”则拆分该行;若同一行多列分号数量相同,仅拆分一次并对应填充各列拆分后的值;不含分号的列复制原行对应值。
原代码问题:不含分隔符的列出现NaN,未正确复制原行值。
原代码问题分析
原代码中使用stack()将各列拆分结果转为多级索引结构,但后续fillna(df[col.name])时,原DataFrame的单级索引无法与多级索引的split_df匹配,导致填充逻辑失效,最终无分隔符的列出现NaN。
修正后的解决方案代码
import pandas as pd data = {'ID': [34, 35], 'Name': ['Alt-Tempelhof Ecke Tempelhofer Damm', 'Alt-Wittenau'], 'Type': ['bus', 'bus'], 'Lines': ['A77,A68,A76', 'A62 ; A15,A21'], 'Coordinates': ['52.465964306830664, 13.38558297633417', '52.58972877186178, 13.334169215342472 ; 52.59166508975595, 13.326326895395114'], 'Extra': [None, 'Alt-Wittenau Ecke Oranienburger Straße ; Alt-Wittenau Ecke Eichborndamm']} df = pd.DataFrame(data) # 计算每行需要拆分的最终行数(分号数+1) def count_semicolons(val): return str(val).count(';') if not pd.isna(val) else 0 df['row_split_num'] = df.apply(lambda row: max(count_semicolons(row[col]) for col in df.columns), axis=1) + 1 # 逐列处理:拆分含分号的列,无分号的列按拆分行数重复原值 processed_columns = [] for col in df.columns.drop('row_split_num'): # 拆分列并去除空格 split_col = df[col].astype(str).str.split(';', expand=True).apply(lambda x: x.str.strip()) # 按当前行的拆分行数扩展列,不足部分用原行首值(无分号列的首值就是原值) expanded_col = split_col.apply( lambda row: pd.Series([row[i] if i < len(row) else row[0] for i in range(df.loc[row.name, 'row_split_num'])]), axis=1 ) # 转为长格式并保留原行索引关联 long_col = expanded_col.stack().reset_index(level=1, drop=True).rename(col) processed_columns.append(long_col) # 合并所有列并重置索引 final_df = pd.concat(processed_columns, axis=1) final_df.reset_index(drop=True, inplace=True) print(final_df)
代码逻辑说明
- 计算拆分行数:统计每行各列的分号数量,取最大值后加1,得到该行需要拆分成的总行数。
- 逐列处理:
- 对含分号的列执行拆分,并去除拆分后值的首尾空格。
- 按该行的拆分行数扩展列:如果拆分后的子项数量不足,用原列的首值(即原行的该列值)补全,保证无分号的列能重复原行值。
- 合并与重置索引:将所有处理后的列合并,重置索引得到最终的拆分结果。
内容的提问来源于stack exchange,提问作者Noah Baumann
相关产品推荐
相关产品推荐

