如何将DataFrame元组行的Items拆分后生成多行数据?
拆分DataFrame中Items字段为多行,保留其他字段不变
问题描述
原始DataFrame如下:
╔════════╦════════════════╦═════════════════════╦═══════════════════════╦═════════════╗ ║ ID ║ Name ║ Address ║ Email ║ Items ║ ╠════════╬════════════════╬═════════════════════╬═══════════════════════╬═════════════╣ ║ 839843 ║ John Smith ║ 55 Apple Lane ║ jsmith@gmail.com ║ 827,937,392 ║ ║ 327569 ║ Tom Hanks ║ 16 Cauliflower Road ║ thanks@gmail.com ║ 947,540 ║ ║ 924852 ║ Alison Johnson ║ 85 Main Street ║ Ajohnson@yahoo.com ║ 838 ║ ║ 949325 ║ Frank Rizzo ║ 218 Orange Road ║ frizzo313@hotmail.com ║ 494,386,285 ║ ║ 373202 ║ Kelly Chang ║ 19 First Avenue ║ kchang@gmail.com ║ 928,502,214 ║ ║ 928436 ║ Lisa Thomas ║ 95 Albany Way ║ lthomas@hotmail.com ║ 455,953 ║ ╚════════╩════════════════╩═════════════════════╩═══════════════════════╩═════════════╝
需要将每行的Items字段按逗号拆分,每个元素对应单独一行,其他字段保持与原行一致,期望输出:
╔════════╦══════╦════════════════╦═════════════════════╦═══════════════════════╗ ║ ID ║ Item ║ Name ║ Address ║ Email ║ ╠════════╬══════╬════════════════╬═════════════════════╬═══════════════════════╣ ║ 839843 ║ 827 ║ John Smith ║ 55 Apple Lane ║ jsmith@gmail.com ║ ║ 839843 ║ 937 ║ John Smith ║ 55 Apple Lane ║ jsmith@gmail.com ║ ║ 839843 ║ 392 ║ John Smith ║ 55 Apple Lane ║ jsmith@gmail.com ║ ║ 327569 ║ 947 ║ Tom Hanks ║ 16 Cauliflower Road ║ thanks@gmail.com ║ ║ 327569 ║ 540 ║ Tom Hanks ║ 16 Cauliflower Road ║ thanks@gmail.com ║ ║ 924852 ║ 838 ║ Alison Johnson ║ 85 Main Street ║ Ajohnson@yahoo.com ║ ║ 949325 ║ 494 ║ Frank Rizzo ║ 218 Orange Road ║ frizzo313@hotmail.com ║ ║ 949325 ║ 386 ║ Frank Rizzo ║ 218 Orange Road ║ frizzo313@hotmail.com ║ ║ 949325 ║ 285 ║ Frank Rizzo ║ 218 Orange Road ║ frizzo313@hotmail.com ║ ║ 373202 ║ 928 ║ Kelly Chang ║ 19 First Avenue ║ kchang@gmail.com ║ ║ 373202 ║ 502 ║ Kelly Chang ║ 19 First Avenue ║ kchang@gmail.com ║ ║ 373202 ║ 214 ║ Kelly Chang ║ 19 First Avenue ║ kchang@gmail.com ║ ║ 928436 ║ 455 ║ Lisa Thomas ║ 95 Albany Way ║ lthomas@hotmail.com ║ ║ 928436 ║ 953 ║ Lisa Thomas ║ 95 Albany Way ║ lthomas@hotmail.com ║ ╚════════╩══════╩════════════════╩═════════════════════╩═══════════════════════╝
原尝试代码未成功:
temp_df = df.iloc[:0] c=0 i=0 for row in df.iterrows(): items = row[1][4].split(',') for item in items: temp_df.at[i+c,:] = row temp_df.at[-1, 'Items'] = item c=c+1 i=i+c c=0
解决方案
方法一:使用Pandas内置函数(推荐,高效简洁)
Pandas的explode()函数专门用于将列表类型的字段拆分为多行,搭配str.split()可以快速实现需求:
import pandas as pd # 1. 将Items字段按逗号拆分为列表 df['Items'] = df['Items'].str.split(',') # 2. 拆分列表为多行 result_df = df.explode('Items') # 3. 重命名列名并重置索引(可选) result_df = result_df.rename(columns={'Items': 'Item'}).reset_index(drop=True) # 可选:去除Item字段的多余空格(如果有的话) result_df['Item'] = result_df['Item'].str.strip() print(result_df)
方法二:修复循环实现
如果必须使用循环,原代码的问题在于索引管理混乱、直接赋值空DataFrame的不存在行导致错误,修复后的代码如下:
import pandas as pd temp_list = [] # 遍历每行,用列名取值更稳健 for _, row in df.iterrows(): items = row['Items'].split(',') for item in items: # 复制原行数据,避免修改原DataFrame new_row = row.copy() # 更新当前Item,去除可能的空格 new_row['Items'] = item.strip() temp_list.append(new_row) # 将列表转为DataFrame temp_df = pd.DataFrame(temp_list) # 重命名列名并重置索引 temp_df = temp_df.rename(columns={'Items': 'Item'}).reset_index(drop=True) print(temp_df)
原代码问题分析
- 索引管理错误:
temp_df初始为空,使用at[i+c,:]赋值不存在的行时,索引逻辑混乱,导致数据覆盖或赋值失败。 - 取值方式不稳健:
row[1][4]按位置取值,一旦列顺序变化就会出错,应该用列名row['Items']。 - 直接修改整行赋值:
temp_df.at[i+c,:] = row后修改Items字段,可能因为引用问题导致原数据被修改,且空DataFrame的at[-1]逻辑不可靠。
内容的提问来源于stack exchange,提问作者Samir112
相关产品推荐
相关产品推荐

