我试图计算一个物体与它的基准之间的差异。我有一个数据集,其中包含所有对象的日常记录及其相应的值,如下所示:
obj_df
date id value_a value_b value_c value_d benchmark_id
01/21/2015 abc 10 41 19 22 efg
01/22/2015 abc 15 43 11 21 efg
01/21/2015 xyz 16 45 13 26 tuv
01/22/2015 xyz 13 48 12 22 tuv
01/21/2015 tru 10 39 15 21 efg
01/21/2015 tru 11 37 13 20 efg
我也有关于基准的数据。值列在数据框之间共享。基准集中的id对应于原始对象数据帧中的基准ID。
bm_df
date id value_a value_b value_c value_d
01/21/2015 efg 12 40 12 20
01/22/2015 efg 15 41 14 21
01/21/2015 tuv 14 42 11 19
01/22/2015 tuv 13 43 19 17
我试图找到一种简单的方法来返回一个数据框,它给出了对象值和相应基准值之间的差异,以获得看起来像这样的数据框。
diff_df
date id diff_a diff_b diff_c diff_d benchmark_id
01/21/2015 abc -2 1 7 2 efg
01/22/2015 abc 0 2 -3 0 efg
01/21/2015 xyz 2 3 2 7 tuv
01/22/2015 xyz 0 5 -7 5 tuv
01/21/2015 tru -4 -3 4 2 efg
01/21/2015 tru -2 -6 -6 3 efg
有几点需要注意:
- 有多个对象而不是基准,因此索引的大小不一样
- 每个对象都有一个基准
- 我并不特别关心原始价值观。差别就是这样
- 某些基准对应于多个对象。例如,两个' abc'和' tru'使用' efg'作为基准。
答案 0 :(得分:4)
我认为您可以使用sub
,然后将id
和benchmark_id
列添加到concat
列,将reindex
列添加到https://jsfiddle.net/63wm1r01/23/列的列中1}}:
obj_df
print (obj_df)
value_a value_b value_c value_d benchmark_id
date id
01/21/2015 abc 10 41 19 22 efg
01/22/2015 abc 15 43 11 21 efg
01/21/2015 xyz 16 45 13 26 tuv
01/22/2015 xyz 13 48 12 22 tuv
print (bm_df)
value_a value_b value_c value_d
date id
01/21/2015 efg 12 40 12 20
01/22/2015 efg 15 41 14 21
01/21/2015 tuv 14 42 11 19
01/22/2015 tuv 13 43 19 17
答案 1 :(得分:3)
odf = obj_df.set_index(['date', 'benchmark_id'])
bdf = bm_df.set_index(['date', 'id'])
odf.update(odf.drop('id', 1).sub(bdf))
odf.reset_index().reindex_axis(obj_df.columns, 1)
答案 2 :(得分:1)
<强> 步骤: 强>
执行合并:
df = obj_df.merge(bm_df, left_on=['benchmark_id', 'date'], right_on=['id', 'date']) \
.drop(['id_y'], 1).set_index(['date'])
通过输入起始和结束列名来查找列索引位置的辅助函数:
def col_locate(df, start, end):
start_loc = df.columns.get_loc(start)
end_loc = df.columns.get_loc(end)
return list(range(start_loc, end_loc+1))
fir, sec = col_locate(df,'value_a_x','value_d_x'), col_locate(df,'value_a_y','value_d_y')
从objectDF
和benchmarkDF
:
df_diff = pd.DataFrame(df.iloc[:, fir].values - df.iloc[:, sec].values,
columns=list('abcd'), index=df.index).add_prefix('diff_')
最后,以列方式连接它们:
pd.concat([df[['id_x', 'benchmark_id']], df_diff], axis=1)
注意: 更新用于获得结果的DF
。
答案 3 :(得分:0)
使用合并:
select.change();