Как вычесть одну строку в другие строки сгруппированы по кадрам данных? - PullRequest
2 голосов
/ 31 октября 2019

У меня есть этот фрейм данных с некоторыми 'init' значениями ('value', 'value2'), которые я хочу вычесть к среднесрочному значению 'mid' и окончательному значению 'final' после группировкиID.

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'], 
 }) 

Также в сгруппированном виде.

1 Ответ

1 голос
/ 31 октября 2019

Использование:

#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
...