我想要合并2个数据。
df1是一个包含合同列表的pandas数据框,其中'year'是合同执行的年份,'o_id'是指该合同来自的组织的id。
df2是一个数据透视表,由多年来组织的问题组成(其中年份是审核组织问题的年份)。 P_1和P_2参考问题1和问题2.
df1
c_id | o_id | year |
====================
101 | 10 | 2013 |
102 | 10 | 2014 |
103 | 10 | 2015 |
103 | 10 | 2016 |
121 | 12 | 2013 |
122 | 12 | 2014 |
123 | 12 | 2015 |
123 | 12 | 2016 |
df2
P_1 | P_2
year | 2013 | 2014 | 2015 | 2013 | 2014 | 2015 |
id |
================================================
10 | 1 | 0 | 0 | 0 | 0 | 0 |
12 | 0 | 1 | 0 | 1 | 1 | 0 |
目的是合并这两个数据集,以便捕获每个合同相对于合同年份的问题的“历史”>执行(合并'df1 ['o_id'] = df2 ['id'])。
请注意,我不能包含执行合同的年份的历史记录(例如,2015年合同只能使用2014年及之前的历史记录)。
我希望最终输出看起来像这样:
id | year | 2013_P_1 | 2014_P_1 | 2015_P_1 | 2013_P_2 | 2014_P_2 | 2015_P_2
===============================================================================
10 | 2013 | NA | NA | NA | NA | NA | NA
10 | 2014 | 1 | NA | NA | 0 | NA | NA
10 | 2015 | 1 | 0 | NA | 0 | 0 | NA
10 | 2016 | 1 | 0 | 0 | 0 | 0 | 0
12 | 2013 | NA | NA | NA | NA | NA | NA
12 | 2014 | 0 | NA | NA | 1 | NA | NA
12 | 2015 | 0 | 1 | NA | 1 | 1 | NA
12 | 2016 | 0 | 1 | 0 | 1 | 1 | 0
答案 0 :(得分:1)
首先通过df2
和stack
join
重新塑造df1
,然后通过自定义函数将NaN
替换为值:
df = (df1.drop('c_id', 1)
.join(df2.stack(0).reset_index(level=1), on='o_id')
.set_index(['o_id','year', 'level_1']))
def f(x):
il1 = np.triu_indices(len(x.columns))
a = x.values.astype(float)
a[il1] = np.nan
x = pd.DataFrame(a, columns=x.columns, index=x.index)
return (x)
df = df.groupby(['o_id','level_1']).apply(f).unstack().sort_index(axis=1, level=1)
df.columns = ['{}_{}'.format(a,b) for a,b in df.columns]
df = df.reset_index()
print (df)
o_id year 2013_P_1 2014_P_1 2015_P_1 2013_P_2 2014_P_2 2015_P_2
0 10 2013 NaN NaN NaN NaN NaN NaN
1 10 2014 1.0 NaN NaN 0.0 NaN NaN
2 10 2015 1.0 0.0 NaN 0.0 0.0 NaN
3 10 2016 1.0 0.0 0.0 0.0 0.0 0.0
4 12 2013 NaN NaN NaN NaN NaN NaN
5 12 2014 0.0 NaN NaN 1.0 NaN NaN
6 12 2015 0.0 1.0 NaN 1.0 1.0 NaN
7 12 2016 0.0 1.0 0.0 1.0 1.0 0.0
答案 1 :(得分:0)
假设您可以更新pivot_table
规范,请考虑转发重复的 Year2 并将 Year 保留在索引中。然后,重命名透视列,然后运行左连接合并:
from itertools import product
...
# NEW PIVOT (ADJUST ACCORDINGLY)
origdf['year2'] = origdf['year']
df2 = origdf.pivot_table(index=['ID', 'year'], columns=['problem'],
values=['year2', 'value'], aggfunc='max')
# RETURN CARTESIAN PRODUCT BETWEEN BOTH PIVOT COLUMN LEVELS
newcols = [str(i[1])+'_'+i[0]
for i in list(product(df2.columns.levels[0], df2.columns.levels[1]))]
# FLATTEN HIERARCHICAL COLUMNS
df2.columns = df2.columns.get_level_values(0)
# REASSIGN COLUMNS
df2.columns = newcols
# RESET MULTI-INDEX BACK AS DF COLUMNS
df2 = df2.reset_index()
# MERGE, DROP UNNEEDED COLS, RE-ORDER COLUMNS
finaldf = df1.merge(df2, left_on=['o_id'], right_on=['id'], how='left')\
.drop(columns=['c_id', 'o_id'])[['id','year'] + newcols]