Найдите соответствующий элемент в двух кадрах и выполните вычитание. - PullRequest
0 голосов
/ 21 января 2020
data1 = pd.DataFrame({'Index':['XX','XX','XX','YY','YY','XY'],'Name':['X1X','X1X','X3X','Y1Y','Y1Y','X1XY'],'Date'['2020/1','2020/1','2020/2','2020/2','2020/2','2020/3'],'ABS':[1,1,2,3,3,4]})
data2 = pd.DataFrame({'Index':['XX','XX','XX','YY','YY'],'Name':['X1X','X1X','X3X','Y1Y','Y1Y'],'Date':['2019/1','2020/1','2020/2','2020/3','2020/3'],'ABS':[1,1,2,3,3]})

d1=data1.groupby(['Index','Name','Date']).sum()
d2=data2.groupby(['Index','Name','Date']).sum()

По сути, у меня есть две структуры данных в этой структуре, как я могу найти элемент с одинаковыми «индексом», «Именем» и «Датой» в d1 и d2 и выполнить вычитание из «АБС» (и поместить это в новом столбце в d2 или в новом кадре данных), если элемент не найден, пометьте его как «Не найдено». Пробовал np. везде, но не работает.

Заранее спасибо.

1 Ответ

0 голосов
/ 21 января 2020

Вот работающее решение, использующее слияние, а затем вычитание.

import pandas as pd
import numpy as np

# make the data
data1 = pd.DataFrame({'Index':['XX','XX','XX','YY','YY','XY'],'Name':['X1X','X1X','X3X','Y1Y','Y1Y','X1XY'],'Date':['2020/1','2020/1','2020/2','2020/2','2020/2','2020/3'],'ABS':[1,1,2,3,3,4]})
data2 = pd.DataFrame({'Index':['XX','XX','XX','YY','YY'],'Name':['X1X','X1X','X3X','Y1Y','Y1Y'],'Date':['2019/1','2020/1','2020/2','2020/3','2020/3'],'ABS':[5,5,6,9,8]})

# do an outer join
data3 = pd.merge(data1, data2, on=['Index', 'Name', 'Date'], how="outer")

# do the subtraction and make a new column, with NaN replaced by 'Not Found'
data3['abs_net'] = np.where((data3['ABS_x'] - data3['ABS_y']).isna(), 'Not Found', (data3['ABS_x'] - data3['ABS_y']))

# drop the two ABS columns
data3 = data3.drop(columns=["ABS_x", "ABS_y"])

# remove duplicate rows
data3 = data3.drop_duplicates()

# look at the result
data3
  Index  Name    Date    abs_net
0    XX   X1X  2020/1        0.0
2    XX   X3X  2020/2        0.0
3    YY   Y1Y  2020/2  Not Found
5    XY  X1XY  2020/3  Not Found
6    XX   X1X  2019/1  Not Found
7    YY   Y1Y  2020/3  Not Found

...