簡體   English   中英

根據pandas中的外鍵減去多個列

[英]Subtract multiple columns based on foreign key in pandas

我試圖計算一個對象和它的基准之間的差異。 我有一個數據集,其中包含所有對象的日常記錄及其對應的值,如下所示:

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'作為基准。

我認為你可以使用sub ,然后通過concat和last reindex列添加列idbenchmark_idobj_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
obj_df.reset_index(level=1, inplace=True)
bm_df.reset_index(level=1, inplace=True)
cols = ['value_a','value_b','value_c', 'value_d']
df = obj_df[cols].sub(bm_df[cols])
df = pd.concat([df, obj_df[['id','benchmark_id']]], axis=1)
       .reindex(columns=obj_df.columns)
       .reset_index()

print (df)
         date   id  value_a  value_b  value_c  value_d benchmark_id
0  01/21/2015  abc       -2        1        7        2          efg
1  01/22/2015  abc        0        2       -3        0          efg
2  01/21/2015  xyz        2        3        2        7          tuv
3  01/22/2015  xyz        0        5       -7        5          tuv
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)

在此輸入圖像描述

腳步:

執行合並:

df = obj_df.merge(bm_df, left_on=['benchmark_id', 'date'], right_on=['id', 'date'])    \
           .drop(['id_y'], 1).set_index(['date'])

Helper函數通過輸入起始和結束列名來查找列索引位置:

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')

objectDFbenchmarkDF減去值:

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用於得出結果。

使用合並:

#inner join on FK
merge = obj_df.merge(bm_df, left_on = 'benchmark_id', right_on = 'id', suffixes = ['_obj', '_bm'])
#create new columns
for value in ['a', 'b', 'c']:
    merge.loc[:, 'diff_%s'%value] = merge['value_%s_obj'%value] - merge['value_%s_bm'%value]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM