Python中是否存在SAS Merge语句的等效实现方式?
SAS按ID合并逻辑的Python等效实现
SAS原逻辑说明
这段SAS代码的核心是按ID分组合并两个表:
- 同
ID组内,两个表的行按顺序对齐 - 如果其中一个表的组内行数更少,就用该组最后一行的值填充后续行
- 最后只保留两个表都存在的
ID组(if inA and inB)
SAS原代码
data have_a; input ID amount_a; datalines; 1 10 1 15 1 20 1 30 2 10 ; data have_b; input ID amount_b; datalines; 1 12 1 14 2 12 2 14 ; data want; merge have_a(in=inA) have_b(in=inb); by id; if inA and inB; run;
预期输出
ID amount_a amount_b 1 10 12 1 15 14 1 20 14 1 30 14 2 10 12 2 10 14
你的Python尝试问题
你用pd.concat直接按列拼接,只是简单对齐行索引,完全没实现SAS的分组对齐+填充逻辑,得到的错误输出:
尝试代码
df1 = pd.DataFrame({'ID': [1, 1, 1, 1, 2], 'A': [10, 15, 20, 30, 10]}) df2 = pd.DataFrame({'ID': [1, 1, 2, 2], 'B': [12, 14, 11, 13]}) pd.concat([df1, df2], axis=1)
错误输出
ID A ID B 0 1 10 1.0 12.0 1 1 15 1.0 14.0 2 1 20 2.0 11.0 3 1 30 2.0 13.0 4 2 10 NaN NaN
Python实现方案
Pandas没有直接对应SAS merge by的函数,但可以通过分组添加行号、扩展短表、合并这三步模拟:
完整代码
import pandas as pd # 定义原始数据 df1 = pd.DataFrame({'ID': [1, 1, 1, 1, 2], 'amount_a': [10, 15, 20, 30, 10]}) df2 = pd.DataFrame({'ID': [1, 1, 2, 2], 'amount_b': [12, 14, 12, 14]}) # 步骤1:给每个ID组添加行序号 df1['row_num'] = df1.groupby('ID').cumcount() df2['row_num'] = df2.groupby('ID').cumcount() # 步骤2:获取每个ID组的最大行号,扩展短表并填充 def expand_and_fill(group, col): max_row = group['row_num'].max() # 重复组内数据直到覆盖最大行号 expanded = group.loc[group.index.repeat(max_row + 1)].reset_index(drop=True) expanded['row_num'] = range(max_row + 1) # 用前向填充保留最后一行的值 expanded[col] = expanded[col].ffill() return expanded df1_expanded = df1.groupby('ID').apply(expand_and_fill, col='amount_a').reset_index(drop=True) df2_expanded = df2.groupby('ID').apply(expand_and_fill, col='amount_b').reset_index(drop=True) # 步骤3:按ID和行号合并,过滤仅保留两表都有的组,整理结果 result = pd.merge(df1_expanded, df2_expanded, on=['ID', 'row_num'], how='inner') result = result[['ID', 'amount_a', 'amount_b']].drop_duplicates() print(result)
运行结果
ID amount_a amount_b 0 1 10 12 1 1 15 14 3 1 20 14 5 1 30 14 6 2 10 12 7 2 10 14
内容的提问来源于stack exchange,提问作者bora bayrak
相关产品推荐
相关产品推荐

