Pandas按ID分组时合并多列非空值实现行扁平化
问题描述
我有一个包含地址和联系信息的Pandas DataFrame,因联系信息存在不同值(同一供应商ID的地址信息一致),行偶尔会重复。示例数据如下:
ID Vendor Name Vendor Address City State Zip Email Phone Name 1 Google 123 Street St Example CA 94000 John 1 Google 123 Street St Example CA 94000 a@b.com 2 Microsoft 456 County Rd Madeup NY 12345 c@d.com 2 Microsoft 456 County Rd Madeup NY 12345 555-1234 2 Microsoft 456 County Rd Madeup NY 12345 Jane
需求是按ID字段分组,将Email、Phone、Name字段扁平化(假设无值冲突),期望结果如下:
ID Vendor Name Vendor Address City State Zip Email Phone Name 1 Google 123 Street St Example CA 94000 a@b.com John 2 Microsoft 456 County Rd Madeup NY 12345 c@d.com 555-1234 Jane
我看到过如下处理单列的方法:
df.groupby(by='ID').apply(lambda group: ','.join(group['Email']))
但该方法仅能处理单列,请问如何实现多列的扁平化处理?
解决方案
可以利用groupby配合agg方法,为不同列指定对应的聚合逻辑。因为你提到无值冲突,同一ID下的Email/Phone/Name只有一个非空值,所以可以提取该列的非空值;而地址类字段(Vendor Name、Vendor Address等)同一ID下值一致,直接取第一个即可。
示例代码如下:
import pandas as pd # 构造示例数据(将原数据的空白转为空字符串) data = { 'ID': [1,1,2,2,2], 'Vendor Name': ['Google','Google','Microsoft','Microsoft','Microsoft'], 'Vendor Address': ['123 Street St','123 Street St','456 County Rd','456 County Rd','456 County Rd'], 'City': ['Example','Example','Madeup','Madeup','Madeup'], 'State': ['CA','CA','NY','NY','NY'], 'Zip': ['94000','94000','12345','12345','12345'], 'Email': ['','a@b.com','c@d.com','',''], 'Phone': ['','','','555-1234',''], 'Name': ['John','','','','Jane'] } df = pd.DataFrame(data) # 定义各字段的聚合规则 agg_rules = { 'Vendor Name': 'first', 'Vendor Address': 'first', 'City': 'first', 'State': 'first', 'Zip': 'first', 'Email': lambda x: x[x != ''].iloc[0], 'Phone': lambda x: x[x != ''].iloc[0], 'Name': lambda x: x[x != ''].iloc[0] } # 分组聚合并保留ID为列(不设为索引) result = df.groupby('ID', as_index=False).agg(agg_rules) print(result)
运行后就能得到期望的扁平化结果。如果你的数据中空值是NaN而非空字符串,只需把聚合逻辑里的x[x != '']替换为x.dropna()即可。
内容的提问来源于stack exchange,提问作者Bijan
相关产品推荐
相关产品推荐

