Pandas — Как вычесть значения строк на основе других столбцов?

#python #pandas

#python #pandas

Вопрос:

Ввод:

   Symbol  Type  Value
0   AAPL   BUY    400
1   AAPL  SELL    310
2   INFY  SELL    190
3    JSL   BUY    120
4    JSW   BUY    190
5    JSW  SELL    170
6    REL   BUY    110
7    TCS   BUY    210
8    TCS  SELL    200
  

Желаемый результат:

  Symbol  Type  Value
0   AAPL   BUY     90
2   INFY  SELL    190
3    JSL   BUY    120
4    JSW   BUY     20
6    REL   BUY    110
7    TCS   BUY     10
  

Как мне добиться такого вывода в pandas? Я попробовал groupby, но это сработало для столбца значений. Я хочу вычесть строки на основе символа типа для значения. Нравится (Символ ПОКУПКА-> Значение) минус (Символ Продажа-> значение)

Ответ №1:

Давайте попробуем

 df.Value *= np.where(df.Type=='BUY', 1, -1)
out = df.groupby('Symbol', as_index=False).agg({'Type':'first','Value':'sum'})
out
Out[152]: 
  Symbol  Type  Value
0   AAPL   BUY     90
1   INFY  SELL   -190
2    JSL   BUY    120
3    JSW   BUY     20
4    REL   BUY    110
5    TCS   BUY     10
  

При необходимости преобразуйте продажу в pos

 out.Value *= np.where(out.Type=='BUY', 1, -1)
out
Out[157]: 
  Symbol  Type  Value
0   AAPL   BUY     90
1   INFY  SELL    190
2    JSL   BUY    120
3    JSW   BUY     20
4    REL   BUY    110
5    TCS   BUY     10
  

Комментарии:

1. Это сработало. Потребовалось некоторое время, чтобы понять это. Все еще выясняю, почему вы использовали оператор *=…

Ответ №2:

 df2 = df.pivot_table(index='Symbol', columns='Type', values='Value', aggfunc='sum').
    fillna(0).eval('Value = BUY - SELL').drop(columns=['BUY', 'SELL']).reset_index()
    
df2.insert(1,'Type', np.where(df2['Value'] > 0, "BUY", "SELL"))
df2['Value'] = abs(df2['Value'])

  
 Type Symbol  Type  Value
0      AAPL   BUY   90.0
1      INFY  SELL  190.0
2       JSL   BUY  120.0
3       JSW   BUY   20.0
4       REL   BUY  110.0
5       TCS   BUY   10.0
  

Ответ №3:

Я не знаю, лучшее ли это решение, но оно определенно должно сработать:

вы можете использовать Numpy для преобразования вашей матрицы pandas в массив, по которому вы можете выполнять цикл, искать значения и т.д. Для вашего примера, когда столбцы типа Buy и следующая строка типа Sell вычитаются (я надеюсь, что я понял вашу проблему прямо здесь, извините за любые неправильные представления), вы могли бы просто использовать цикл for, который создает два массива, один типа Sell и один типа Buy, а затем вычитает значение 1 из первого массива и значение 1 из второго или что-то в этом роде. Это определенно не так хорошо, как другой ответ на этот вопрос, по крайней мере, не в этом случае, но я верю, что в нем есть случаи, когда это могло бы быть намного лучше, например, потому что numpy позволяет изменять форму массива

Комментарии:

1. Цикл не кажется лучшим вариантом. И в любом случае, OP, скорее всего, найдет более полезным некоторый код, показывающий, как это можно сделать