Как рассчитать pct_change в панд со ссылкой только на первый столбец

#python #pandas

Вопрос:

У меня есть фрейм данных в виде:

 df = pd.DataFrame({
    "A": [1, 5, 2, 5, 6],
    "B": [-12, 23, 5, 22, 35],
    "C": [-32, 12, -10, 3, 2],
    "D": [2, 13, 6, 2, 8]
})
 

Теперь я хочу рассчитать процентное изменение axis=1 , но со ссылкой только "A" на все столбцы , такие как процентное изменение для "B" w.r.t "A" , "C" w.r.t "A" и так далее.

pct_change Функция выполняет аналогичную работу, но она вычисляет процентное изменение для последовательных строк или столбцов, которые мне не нужны.

Прямо сейчас я думаю о том, чтобы достичь этого , вероятно, с помощью цикла for и добавления процентов ИЛИ разделения фрейма данных, например ["A", "B"] , ["A", "C"] , и так далее, а затем применить pct_change ко всем отдельно.

Последний подход, я думаю, лучше, но вопрос в том,,

Есть ли еще лучший подход, который будет выполнять ту же работу?

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

1. Пожалуйста, добавьте также ожидаемый результат. pct_change также поддерживает параметры для DataFrame.shift и Series.shift поэтому возможно достижение требуемого результата с помощью pct_change

Ответ №1:

Вы можете использовать функцию разделения в панд, ныряя во все столбцы с помощью столбца A

 pct = df.divide(df["A"], axis="index") - 1
pct.head()
 

Результаты:

A B C D
0 0.0 -13.000000 -33.000000 1.000000
1 0.0 3.600000 1.400000 1.600000
2 0.0 1.500000 -6.000000 2.000000
3 0.0 3.400000 -0.400000 -0.600000
4 0.0 4.833333 -0.666667 0.333333

Ответ №2:

Вы можете легко эмулировать pct_change w.r.t. A с DataFrame.sub помощью и DataFrame.div для вашего случая.

 df.loc[:, 'B':].sub(df['A'], axis=0).div(df['A'], axis=0)

           B          C         D
0 -13.000000 -33.000000  1.000000
1   3.600000   1.400000  1.600000
2   1.500000  -6.000000  2.000000
3   3.400000  -0.400000 -0.600000
4   4.833333  -0.666667  0.333333
 

Ответ №3:

Вы можете использовать **кварги для assign()

     "A": [1, 5, 2, 5, 6],
    "B": [-12, 23, 5, 22, 35],
    "C": [-32, 12, -10, 3, 2],
    "D": [2, 13, 6, 2, 8]
})

basecol = "A"
df.assign(**{f"{c}_pct":df[basecol]/df[c] for c in df.columns if c!=basecol})
 
A B C D B_pct C_pct D_pct
0 1 -12 -32 2 -0.0833333 -0.03125 0.5
1 5 23 12 13 0.217391 0.416667 0.384615
2 2 5 -10 6 0.4 -0.2 0.333333
3 5 22 3 2 0.227273 1.66667 2.5
4 6 35 2 8 0.171429 3 0.75