如何将含相同SSN的行横向展示并统计关联唯一ID数量?
解决方案:按SSN分组并横向展示用户信息
嘿,我来帮你搞定这个需求!要把相同SSN的用户信息横向排列,同时统计每个SSN对应的唯一ID数量,用Python的pandas或者SQL都能实现,下面是具体的方案:
Python实现方案(灵活处理任意数量同SSN记录)
Python的pandas库非常适合处理这种表格数据的分组和转置需求,能自动适配同一SSN下不同数量的用户记录,不用手动写死列数。
完整代码
import pandas as pd # 1. 构造原始数据(如果是从CSV/Excel读取,替换成pd.read_csv("your_file.csv")即可) data = [ ["000000000", 1, "JANE", "DOE"], ["123456789", 2, "PETE", "PETER"], ["123456789", 3, "JOHN", "SHAW"], ["234567890", 4, "ALAN", "DAVID"], ["234567890", 5, "MAY", "APRI"], ["345677891", 6, "JUNE", "ALYSSA"], ["456789123", 7, "LISA", "LINH"], ["567891234", 8, "HAL", "LEY"], ["567891234", 9, "DEREK", "LI"], ["567891234", 10, "JIM", "JAMES"] ] df = pd.DataFrame(data, columns=["SSN", "ID", "F_NAME", "L_NAME"]) # 2. 定义分组处理函数:将组内记录横向展开,添加后缀 def process_ssn_group(group): # 统计当前SSN的用户数量 user_count = len(group) # 重置组内索引,方便生成列后缀 group = group.reset_index(drop=True) # 初始化结果字典,先存入SSN和COUNT result = {"SSN": group["SSN"].iloc[0], "COUNT": user_count} # 遍历组内每一条记录,横向写入结果 for idx, row in group.iterrows(): if idx == 0: # 第一条记录用原列名(ID/F_NAME/L_NAME) result["ID"] = row["ID"] result["F_NAME"] = row["F_NAME"] result["L_NAME"] = row["L_NAME"] else: # 后续记录添加_2/_3这样的后缀 suffix = f"_{idx+1}" result[f"ID{suffix}"] = row["ID"] result[f"F_NAME{suffix}"] = row["F_NAME"] result[f"L_NAME{suffix}"] = row["L_NAME"] return pd.Series(result) # 3. 按SSN分组并应用处理函数,整理最终结果 final_result = df.groupby("SSN").apply(process_ssn_group).reset_index(drop=True) # 4. 调整列顺序,和需求格式一致 columns_order = ["SSN", "COUNT"] # 提取所有带后缀的列,找到最大的后缀数 suffix_cols = [col for col in final_result.columns if "_" in col] if suffix_cols: max_suffix = max(int(col.split("_")[1]) for col in suffix_cols) # 依次添加第一组、第二组...的列 for i in range(1, max_suffix + 1): if i == 1: columns_order.extend(["ID", "F_NAME", "L_NAME"]) else: columns_order.extend([f"ID_{i}", f"F_NAME_{i}", f"L_NAME_{i}"]) else: columns_order.extend(["ID", "F_NAME", "L_NAME"]) final_result = final_result[columns_order] # 打印输出(如果要保存到文件,用final_result.to_csv("output.csv", index=False)) print(final_result.to_string(index=False))
代码说明
- 自动识别每个SSN下的用户数量,动态生成对应的
ID_2/F_NAME_2等列 - 支持从CSV/Excel文件读取原始数据,只需替换构造DataFrame的部分
- 最终输出的列顺序完全匹配你给出的示例格式
SQL实现方案(适合数据库场景)
如果你的数据存储在数据库里,也可以用SQL的窗口函数和条件聚合来实现,缺点是需要提前知道同一SSN下的最大用户数(比如示例里最多3个,就写3组CASE语句)。
示例SQL代码
WITH numbered_records AS ( -- 给每个SSN分组内的记录编号 SELECT SSN, ID, F_NAME, L_NAME, ROW_NUMBER() OVER (PARTITION BY SSN ORDER BY ID) AS record_num FROM your_table_name ) SELECT SSN, COUNT(*) AS COUNT, -- 第一组用户信息 MAX(CASE WHEN record_num = 1 THEN ID END) AS ID, MAX(CASE WHEN record_num = 1 THEN F_NAME END) AS F_NAME, MAX(CASE WHEN record_num = 1 THEN L_NAME END) AS L_NAME, -- 第二组用户信息 MAX(CASE WHEN record_num = 2 THEN ID END) AS ID_2, MAX(CASE WHEN record_num = 2 THEN F_NAME END) AS F_NAME_2, MAX(CASE WHEN record_num = 2 THEN L_NAME END) AS L_NAME_2, -- 第三组用户信息(如果有更多,继续添加) MAX(CASE WHEN record_num = 3 THEN ID END) AS ID_3, MAX(CASE WHEN record_num = 3 THEN F_NAME END) AS F_NAME_3, MAX(CASE WHEN record_num = 3 THEN L_NAME END) AS L_NAME_3 FROM numbered_records GROUP BY SSN ORDER BY SSN;
说明
- 用
ROW_NUMBER()给每个SSN下的记录排序编号 - 用
MAX(CASE...)实现转置,把纵向的记录变成横向的列 - 如果同一SSN下的用户超过3个,需要手动添加更多的CASE语句块
内容的提问来源于stack exchange,提问作者Dave Jabbz
相关产品推荐
相关产品推荐

