Вычитание столбцов на основе ключевого столбца в кадре данных панд - PullRequest
0 голосов
/ 03 мая 2018

У меня есть два кадра данных, выглядящих как

df1:

   ID    A   B   C   D 
0 'ID1' 0.5 2.1 3.5 6.6
1 'ID2' 1.2 5.5 4.3 2.2
2 'ID1' 0.7 1.2 5.6 6.0 
3 'ID3' 1.1 7.2 10. 3.2

df2:

   ID    A   B   C   D 
0 'ID1' 1.0 2.0 3.3 4.4
1 'ID2' 1.5 5.0 4.0 2.2
2 'ID3' 0.6 1.2 5.9 6.2 
3 'ID4' 1.1 7.2 8.5 3.0

df1 может иметь несколько записей с одинаковым ID, тогда как каждый ID встречается только один раз в df2. Также не все ID в df2 обязательно присутствуют в df1. Я не могу решить эту проблему с помощью set_index(), так как несколько строк в df1 могут иметь одинаковый ID, и что ID в df1 и df2 не выровнены.

Я хочу создать новый фрейм данных, в котором я вычитаю значения в df2[['A','B','C','D']] из df1[['A','B','C','D']] на основе сопоставления идентификатора.

Полученный кадр данных будет выглядеть так:

df_new:

   ID     A    B   C   D 
0 'ID1' -0.5  0.1 0.2 2.2
1 'ID2' -0.3  0.5 0.3 0.0
2 'ID1' -0.3 -0.8 2.3 1.6
3 'ID3'  0.5  6.0 1.5 0.2

Я знаю, как сделать это с помощью цикла, но, поскольку я имею дело с огромными объемами данных, это вообще не практично. Как лучше всего подойти к этому с помощью панд?

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Подобно тому, что предлагал Вэнь (который избил меня), вы можете использовать pd.DataFrame.subtract:

df1.set_index('ID').subtract(df2.set_index('ID')).reset_index()

         A    B    C    D
ID                       
'ID1' -0.5  0.1  0.2  2.2
'ID1' -0.3 -0.8  2.3  1.6
'ID2' -0.3  0.5  0.3  0.0
'ID3'  0.5  6.0  4.1 -3.0
0 голосов
/ 03 мая 2018

Один из методов - использовать numpy. Мы можем извлечь требуемые индексы из df2, используя numpy.searchsorted.

Затем вставьте это в конструкцию нового фрейма данных.

idx = np.searchsorted(df2['ID'], df1['ID'])

res = pd.DataFrame(df1.iloc[:, 1:].values - df2.iloc[:, 1:].values[idx],
                   index=df1['ID']).reset_index()

print(res)

      ID    0    1    2    3
0  'ID1' -0.5  0.1  0.2  2.2
1  'ID2' -0.3  0.5  0.3  0.0
2  'ID1' -0.3 -0.8  2.3  1.6
3  'ID3'  0.5  6.0  4.1 -3.0
0 голосов
/ 03 мая 2018

Вам просто нужно установить set_index и вычесть

(df1.set_index('ID')-df2.set_index('ID')).dropna(axis=0)
Out[174]: 
         A    B    C    D
ID                       
'ID1' -0.5  0.1  0.2  2.2
'ID1' -0.3 -0.8  2.3  1.6
'ID2' -0.3  0.5  0.3  0.0
'ID3'  0.5  6.0  4.1 -3.0

Если заказ имеет значение, добавьте reindex для df2

(df1.set_index('ID')-df2.set_index('ID').reindex(df1.ID)).dropna(axis=0).reset_index()
Out[211]: 
      ID    A    B    C    D
0  'ID1' -0.5  0.1  0.2  2.2
1  'ID2' -0.3  0.5  0.3  0.0
2  'ID1' -0.3 -0.8  2.3  1.6
3  'ID3'  0.5  6.0  4.1 -3.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...