如何将多列UserID与Amount数据合并并按UserID汇总金额?
问题描述
现有如下结构的宽表,每行包含多组UserID和对应的Amount,同一UserID可能出现在不同行的不同列中:
| UserID1 | Amount1 | UserID2 | Amount2 | ..... | UserIDN | AmountN |
|---|---|---|---|---|---|---|
| 1 | 10 | 2 | 15 | ..... | 125 | 30 |
| 2 | 26 | 5 | 17 | ..... | 3 | 26 |
| 125 | 17 | 3 | 22 | ..... | 1 | 20 |
需要将所有行中同一UserID对应的Amount求和,生成如下结构的汇总表:
| UserID | Amount |
|---|---|
| 1 | 30 |
| 2 | 41 |
| 3 | 48 |
| 125 | 47 |
| 5 | 17 |
最优实现方法
根据使用场景不同,推荐以下几种最优方案:
1. 办公软件(Excel/Google Sheets)—— 非编程场景
这是普通用户最便捷的方案,无需写代码:
- 第一步:整理数据:把分散的
UserID和Amount合并成两列。比如在Excel中:- 新列A输入
=INDEX($A:$Z,ROW(),COLUMN()*2-1)提取所有UserID,下拉+右拉覆盖所有数据; - 新列B输入
=INDEX($A:$Z,ROW(),COLUMN()*2)提取对应Amount,同样下拉+右拉; - 复制这两列数据,粘贴为值后删除空行。
- 新列A输入
- 第二步:汇总求和:用数据透视表效率最高:
选中整理后的两列 → 插入数据透视表 → 将UserID拖到「行」区域,Amount拖到「值」区域 → 设置值汇总方式为「求和」即可。
2. Python(Pandas)—— 编程/大数据场景
如果数据量较大或需要自动化处理,Pandas是最优选择,两种实现方式:
方式一:宽表转窄表(规范写法)
import pandas as pd # 读取数据(替换为你的数据路径或直接构造DataFrame) df = pd.read_csv("your_data.csv") # 将宽表重塑为包含列名和值的长表 melted = pd.melt(df, var_name="col", value_name="val") # 拆分列名中的类型(UserID/Amount)和序号 melted["type"] = melted["col"].str.split("(\d+)").str[0] melted["idx"] = melted["col"].str.split("(\d+)").str[1] # 重新转为宽表,匹配UserID和对应Amount pivoted = melted.pivot(index="idx", columns="type", values="val").reset_index(drop=True) pivoted.columns = ["UserID", "Amount"] # 转换数据类型并按UserID求和 result = pivoted.astype({"UserID": int, "Amount": int}).groupby("UserID")["Amount"].sum().reset_index() print(result)
方式二:直接遍历列对(简洁写法)
import pandas as pd df = pd.read_csv("your_data.csv") user_totals = {} # 遍历每一组UserID和Amount列 for i in range(0, len(df.columns), 2): user_col = df.columns[i] amount_col = df.columns[i+1] # 累加每个UserID的Amount for user, amt in zip(df[user_col], df[amount_col]): user_totals[user] = user_totals.get(user, 0) + amt # 转成目标格式的DataFrame result = pd.DataFrame(user_totals.items(), columns=["UserID", "Amount"]) print(result)
3. SQL—— 数据库场景
如果数据存储在数据库中,用UNION ALL合并所有列对后分组求和:
SELECT UserID, SUM(Amount) AS Amount FROM ( -- 依次列出所有UserID和Amount列对 SELECT UserID1 AS UserID, Amount1 AS Amount FROM user_amounts UNION ALL SELECT UserID2 AS UserID, Amount2 AS Amount FROM user_amounts UNION ALL -- ... 重复直到所有列对都被包含 SELECT UserIDN AS UserID, AmountN AS Amount FROM user_amounts ) AS combined GROUP BY UserID ORDER BY UserID;
内容的提问来源于stack exchange,提问作者mikhailitsky
相关产品推荐
相关产品推荐

