Создайте новый столбец фрейма данных из смещенного существующего столбца

#python #pandas #series

Вопрос:

У меня есть фрейм данных с ценами открытия, максимума, минимума и закрытия акций. Я хочу добавить дополнительный столбец с процентным изменением между сегодняшним открытием и вчерашним максимумом. Это моя текущая реализация, однако результирующий столбец содержит процентные изменения между максимумом текущего дня и открытием.

df

   open  high  low  close
0 100   110   95   103
1 103   113   103   111
2 111   132   109   124
3 124   136   114   130
 

Моя попытка (неверная):

 df['prevhigh_curropen'] = (df['open'] - df['high']).shift(-1) / df['high'].shift(-1)
 

Вывод (неверный):

   open  high  low  close  prevhigh_curropen
0 100   110   95   103    -0.091
1 103   113   103  111    -0.089
2 111   132   109  124    -0.159
3 124   136   114  130    -0.088
 

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

   open  high  low  close  prevhigh_curropen
0 100   110   95   103    nan
1 103   113   103  111    -0.064
2 111   132   109  124    -0.018
3 124   136   114  130    -0.061
 

Есть ли неитеративный способ сделать это, как я пытался сделать выше?

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

1. Можете ли вы обновить свой пост с выводом print(df[['open', 'high']].head(10).to_string(index=False)) , пожалуйста?

2. Похоже, ты просто меняешь неправильное направление (df['open'] - df['high'].shift()) / df['high'].shift()

Ответ №1:

Ваша формула неверна, вы должны использовать df['high'].shift() :

 df = pd.DataFrame({'open': range(1, 11), 'high': range(1, 11)})
df['prevhigh_curropen'] = df['open'].sub(df['high'].shift()) 
                                    .div(df['high'].shift()) 
                                    .mul(100)
 
 >>> df
   open  high  prevhigh_curropen
0     1     1                NaN
1     2     2         100.000000
2     3     3          50.000000
3     4     4          33.333333
4     5     5          25.000000
5     6     6          20.000000
6     7     7          16.666667
7     8     8          14.285714
8     9     9          12.500000
9    10    10          11.111111
 

Для вашего образца вывод будет:

 >>> df
   open  high  low  close  prevhigh_curropen
0   100   110   95    103                NaN
1   103   113  103    111          -6.363636
2   111   132  109    124          -1.769912
3   124   136  114    130          -6.060606
 

Первое значение NaN связано с тем, что мы не знаем high значения за предыдущий день.

Ответ №2:

Мы можем немного упростить термины от (a - b) / b до (a / b) - (b / b) до (a / b) - 1 .

Математические операторы:

 df['prevhigh_curropen'] = (df['open'] / df['high'].shift()) - 1
 

или с помощью последовательных методов:

 df['prevhigh_curropen'] = df['open'].div(df['high'].shift()).sub(1)
 

*Преимущество здесь в том, что нам нужно только один раз переключиться и сохранить 1 копию df['high'].shift()

Конечный df :

    open  high  low  close  prevhigh_curropen
0   100   110   95    103                NaN
1   103   113  103    111          -0.063636
2   111   132  109    124          -0.017699
3   124   136  114    130          -0.060606
 

Используемая Настройка:

 import pandas as pd

df = pd.DataFrame({
    'open': [100, 103, 111, 124],
    'high': [110, 113, 132, 136],
    'low': [95, 103, 109, 114],
    'close': [103, 111, 124, 130]
})