Pandas处理CSV:匹配Name与Email Name列对齐对应行值
问题背景
现有4列CSV文件,列结构与示例数据如下:
Name Dept Email Name Hair Color John Smith candy Lincoln Tun brown Diana Princ candy John Smith gold Perry Plat wood Oliver Twist bald Jerry Springer clothes Diana Princ gold Calvin Klein clothes Lincoln Tun warehouse Oliver Twist kitchen
需求为按姓名匹配Name和Email Name两列,将同一姓名对应的属性对齐到同一行,期望输出效果如下:
Name Dept Email Name Hair Color John Smith candy John Smith gold Diana Princ candy Diana Princ gold Perry Plat wood Jerry Springer clothes Calvin Klein clothes Lincoln Tun warehouse Lincoln Tun brown Oliver Twist kitchen Oliver Twist bald
原有实现的问题
原有核心逻辑代码如下:
dfs = np.split(df,len(df.columns), axis=1) dfs = [df.set_index(df.columns[0], drop=False) for df in dfs] f=dfs[0].join(dfs[1:]).reset_index(drop=True).fillna(0)
运行后Name和Email Name列匹配排序符合预期,但其余列非空值全部被填充为0,实际输出如下:
Name Dept Email Name Hair Color John Smith 0 John Smith 0 Diana Princ 0 Diana Princ 0 Perry Plat 0 0 0 Jerry Springer 0 0 0 Calvin Klein 0 0 0 Lincoln Tun 0 Lincoln Tun 0 Oliver Twist 0 Oliver Twist 0
原有完整可运行代码:
import pandas as pd import numpy as np import os, csv, sys csvPath = 'User.csv' df= pd.read_csv(csvPath) dfs = np.split(df,len(df.columns), axis=1) dfs = [df.set_index(df.columns[0], drop=False) for df in dfs] f=dfs[0].join(dfs[1:]).reset_index(drop=True).fillna(0) testCSV = 'test_user.csv' f.to_csv(testCSV, encoding='utf-8')
错误原因
使用np.split按列拆分后,对每个单列表执行set_index(df.columns[0])时:
- 拆分出的
Name列表索引为姓名字符串 - 拆分出的
Email Name列表索引为邮箱姓名字符串,和Name列的索引值范围一致,因此join时可以匹配 - 拆分出的
Dept列表索引为部门字符串、Hair Color列表索引为发色字符串,和Name列的姓名索引完全不匹配,join后这两列全部为空值,后续执行fillna(0)就会把所有空值填为0,导致原有数据丢失。
正确实现代码
直接通过字典映射完成属性对齐,不需要拆分DataFrame做join:
import pandas as pd csvPath = 'User.csv' df = pd.read_csv(csvPath) # 构建姓名到部门、邮箱名到发色的映射字典 dept_map = df.dropna(subset=['Name']).set_index('Name')['Dept'].to_dict() hair_map = df.dropna(subset=['Email Name']).set_index('Email Name')['Hair Color'].to_dict() # 以原表Name列为基准构建结果 result = pd.DataFrame() result['Name'] = df['Name'].dropna().unique() result['Dept'] = result['Name'].map(dept_map) result['Email Name'] = result['Name'] result['Hair Color'] = result['Name'].map(hair_map) testCSV = 'test_user.csv' result.to_csv(testCSV, encoding='utf-8', index=False)
运行后输出结果和预期完全一致,不会出现原有列被错误填0的问题。
内容的提问来源于stack exchange,提问作者noobCoder
相关产品推荐
相关产品推荐

