PySpark如何实现DataFrame透视:将多类型行转换为宽表?
实现DataFrame的透视转换方法
针对你给出的DataFrame结构,有两种常用方法可以实现目标转换:
方法一:合并列后透视
先将value和number列根据type合并为统一的内容列,再执行透视操作:
import pandas as pd import numpy as np # 构造原始数据(实际使用时替换为你的DataFrame) df = pd.DataFrame({ 'user_id': ['user_id1', 'user_id1', 'user_id2', 'user_id2'], 'type': ['email', 'phone', 'email', 'phone'], 'value': ['abc@abc.com', '', 'def@def.com', ''], 'number': ['', '12345', '', '67890'] }) # 合并value和number列:email取value值,phone取number值 df['content'] = np.where(df['type'] == 'email', df['value'], df['number']) # 透视生成目标结构 result_df = df.pivot(index='user_id', columns='type', values='content').reset_index() # 移除列索引的名称 result_df.columns.name = None print(result_df)
执行后输出的结果就是你期望的结构:
user_id email phone 0 user_id1 abc@abc.com 12345 1 user_id2 def@def.com 67890
方法二:拆分合并法
分别提取email和phone对应的数据,再通过user_id合并:
import pandas as pd # 构造原始数据 df = pd.DataFrame({ 'user_id': ['user_id1', 'user_id1', 'user_id2', 'user_id2'], 'type': ['email', 'phone', 'email', 'phone'], 'value': ['abc@abc.com', '', 'def@def.com', ''], 'number': ['', '12345', '', '67890'] }) # 提取email数据并重命名列 email_df = df[df['type'] == 'email'][['user_id', 'value']].rename(columns={'value': 'email'}) # 提取phone数据并重命名列 phone_df = df[df['type'] == 'phone'][['user_id', 'number']].rename(columns={'number': 'phone'}) # 合并两个DataFrame result_df = pd.merge(email_df, phone_df, on='user_id') print(result_df)
这种方法逻辑更直观,适合type种类较少的场景;如果后续type新增其他类别,方法一的扩展性更强。
内容的提问来源于stack exchange,提问作者Tony Dang
相关产品推荐
相关产品推荐

