如何使用Pandas拆分含列表的CSV列并生成独立CSV文件
需求说明
我有一份从API获取的多列CSV文件,部分单元格存储单个值,部分是列表/数组格式。同一CSV内的所有列表列长度一致,但不同CSV的列表长度会随API响应变化。需要用pandas将列表列中的每个元素拆分出来,生成独立的CSV文件,同时保留其余列的数据。
以下是模拟生成的示例数据代码:
import random import csv # 预定义NAME、CARS和PHONE_OS的列表 NAMES = ["John Doe", "Jane Smith", "Alice Johnson", "Bob Brown", "Charlie Davis", "Eve White", "David Wilson", "Emma Taylor", "Frank Harris", "Grace Clark"] CAR_BRANDS = ["Toyota", "Ford", "BMW", "Tesla", "Honda", "Chevrolet", "Nissan", "Audi"] PHONE_OS = ["Android", "iOS"] def create_csv(file_name, num_records): cur_random_list_size = random.randint(1, min(len(NAMES), len(CAR_BRANDS))) with open(file_name, mode='w', newline='') as file: writer = csv.writer(file) writer.writerow(["ID", "NAME", "MONTH", "CARS", "PHONE OS"]) for i in range(num_records): record = { "id" : i + 1, "name": [NAMES[n] for n in range(cur_random_list_size)], "month": random.randint(1,12), "cars": [random.choice(CAR_BRANDS) for _ in range(cur_random_list_size)], "phone": random.choice(PHONE_OS) } writer.writerow(record.values()) print(f"CSV file '{file_name}' created with {num_records} records.") create_csv("people_data.csv", 5)
生成的示例CSV内容如下:
| ID | NAME | MONTH | CARS | PHONE OS |
|---|---|---|---|---|
| 1 | "['John Doe', 'Jane Smith', 'Alice Johnson', 'Bob Brown', 'Charlie Davis', 'Eve White']" | 2 | "['Toyota', 'Nissan', 'Nissan', 'Nissan', 'Audi', 'Honda']" | iOS |
| 2 | "['John Doe', 'Jane Smith', 'Alice Johnson', 'Bob Brown', 'Charlie Davis', 'Eve White']" | 4 | "['Nissan', 'Ford', 'Honda', 'Toyota', 'Ford', 'Honda']" | iOS |
| 3 | "['John Doe', 'Jane Smith', 'Alice Johnson', 'Bob Brown', 'Charlie Davis', 'Eve White']" | 8 | "['BMW', 'Honda', 'Tesla', 'Tesla', 'Tesla', 'Nissan']" | Android |
| 4 | "['John Doe', 'Jane Smith', 'Alice Johnson', 'Bob Brown', 'Charlie Davis', 'Eve White']" | 3 | "['Tesla', 'Audi', 'Chevrolet', 'Audi', 'Chevrolet', 'BMW']" | iOS |
| 5 | "['John Doe', 'Jane Smith', 'Alice Johnson', 'Bob Brown', 'Charlie Davis', 'Eve White']" | 8 | "['Ford', 'Tesla', 'BMW', 'Toyota', 'Nissan', 'Ford']" | Android |
期望输出为每个列表元素生成独立CSV,例如john_doe_people_data.csv的内容:
| ID | NAME | MONTH | CARS | PHONE OS |
|---|---|---|---|---|
| 1 | John Doe | 2 | Toyota | iOS |
| 2 | John Doe | 4 | Nissan | iOS |
| 3 | John Doe | 8 | BMW | Android |
| 4 | John Doe | 3 | Tesla | iOS |
| 5 | John Doe | 8 | Ford | Android |
解决方案
步骤1:导入依赖库
需要用到pandas处理表格数据,ast解析字符串格式的列表:
import pandas as pd import ast
步骤2:读取并解析CSV文件
CSV中的列表以字符串形式存储,用ast.literal_eval转换为实际的Python列表:
# 读取CSV df = pd.read_csv("people_data.csv") # 解析列表格式的列 df["NAME"] = df["NAME"].apply(ast.literal_eval) df["CARS"] = df["CARS"].apply(ast.literal_eval)
步骤3:同步展开所有列表列
利用pandas.DataFrame.explode方法,同时展开所有列表列,确保同一行的列表元素一一对应:
# 展开列表列,重置索引 df_exploded = df.explode(["NAME", "CARS"], ignore_index=True)
步骤4:按目标列分组并导出独立CSV
以NAME列为分组依据,为每个分组生成单独的CSV文件,文件名采用小写下划线格式:
# 按NAME分组,遍历每个分组 for name, group in df_exploded.groupby("NAME"): # 生成规范的文件名 filename = f"{name.lower().replace(' ', '_')}_people_data.csv" # 导出CSV,不保留索引 group.to_csv(filename, index=False)
完整代码
import pandas as pd import ast # 读取并解析CSV df = pd.read_csv("people_data.csv") df["NAME"] = df["NAME"].apply(ast.literal_eval) df["CARS"] = df["CARS"].apply(ast.literal_eval) # 展开列表列 df_exploded = df.explode(["NAME", "CARS"], ignore_index=True) # 分组导出CSV for name, group in df_exploded.groupby("NAME"): filename = f"{name.lower().replace(' ', '_')}_people_data.csv" group.to_csv(filename, index=False) print(f"已生成文件: {filename}")
关键说明
ast.literal_eval安全解析字符串格式的列表,避免使用eval带来的风险。explode方法支持同时传入多个列名,确保同一行的列表元素同步展开,不会出现错位。- 分组时使用
groupby,遍历每个分组并导出,文件名根据分组值自动生成,保证唯一性。
内容的提问来源于stack exchange,提问作者kyrlon
相关产品推荐
相关产品推荐

