首页 > 解决方案 > 如何在按数据帧分组的其他行中减去一行?

问题描述

我有这个数据框,其中包含一些'init'值('value', ),一旦按 ID 分组'value2',我想减去中期值'mid'和最终值。'final'

import pandas as pd
df = pd.DataFrame({ 
    'value': [100, 120, 130, 200, 190,210],
    'value2': [2100, 2120, 2130, 2200, 2190,2210],  
     'ID': [1, 1, 1, 2, 2, 2], 
     'state': ['init','mid', 'final', 'init', 'mid', 'final'], 
 })

我的尝试是提取我找到的索引'init''mid'并从我将值分组后的值 中'final'减去:'mid''final''init''ID'

group = df.groupby('ID')
group['diff_1_f'] = group['value'].iloc[group.index[group['state'] == 'final'] - group['value'].iloc[group.index[dfs['state'] == 'init']]]]
group['diff_2_f'] =  group['value2'].iloc[group.index[group['state'] == 'final'] - group['value'].iloc[group.index[dfs['state'] == 'init']]]
group['diff_1_m'] = group['value'].iloc[group.index[group['state'] == 'mid'] - group['value'].iloc[group.index[dfs['state'] == 'init']]]
group['diff_2_m'] =  group['value2'].iloc[group.index[group['state'] == 'mid'] - group['value'].iloc[group.index[dfs['state'] == 'init']]]  

但它当然行不通。如何获得以下结果:

df = pd.DataFrame({ 
    'diff_value': [20, 30, -10,10],
    'diff_value2': [20, 30, -10,10],  
     'ID': [ 1, 1, 2, 2], 
     'state': ['mid', 'final', 'mid', 'final'], 
 }) 

也是分组形式。

标签: pandasrowpandas-groupbysubtraction

解决方案


利用:

#columns names in list for subtract
cols = ['value', 'value2']
#new columns names created by join
new = [c + '_diff' for c in cols]
#filter rows with init
m = df['state'].ne('init')

#add init rows to new columns by  join and filter no init rows
df1 = df.join(df[~m].set_index('ID')[cols], lsuffix='_diff', on='ID')[m]
#subtract with numpy array by .values for prevent index alignment
df1[new] = df1[new].sub(df1[cols].values)
#remove helper columns
df1 = df1.drop(cols, axis=1)
print (df1)
   value_diff  value2_diff  ID  state
1          20           20   1    mid
2          30           30   1  final
4         -10          -10   2    mid
5          10           10   2  final

推荐阅读