Рассчитайте ежемесячное процентное изменение ежедневных данных в Python

#python-3.x #pandas #dataframe #numpy #date

Вопрос:

Допустим, у меня есть ежедневные данные следующим образом:

 import pandas as pd import numpy as np  np.random.seed(2021) dates = pd.date_range('20130226', periods=90) df = pd.DataFrame(np.random.randint(0, 100, size=(90, 3)), index=dates, columns=list('ABC')) df  

Из:

 A B C 2013-02-26 85 57 0 2013-02-27 94 86 44 2013-02-28 62 91 29 2013-03-01 21 93 24 2013-03-02 12 70 70  .. .. .. 2013-05-22 57 13 81 2013-05-23 43 68 85 2013-05-24 55 50 53 2013-05-25 75 78 66 2013-05-26 70 93 3  

Для столбца A и B мне нужно рассчитать их ежемесячное изменение pct на ежедневной основе , например, значение ежемесячного изменения pct A для 2013-05-26 будет рассчитываться по: значению A в 2013-05-26, деленному на значение в 2013-04-26 минус 1.

Моя идея заключается в следующем: создайте новые столбцы 'A1', 'B1' , переместив их на один месяц вперед, затем df['A_MoM'] они будут рассчитываться по df['A']/df['A_shifted'] - 1 той же логике для столбца B .

Поскольку не все месяцы имеют одинаковую продолжительность дней, поэтому я буду использовать значение последнего дня за последние месяцы, т. Е. Для расчета изменения pct 2013-03-30 будет рассчитываться по формуле: 2013-03-30's value/2013-02-28's value - 1 .

Я попробовал приведенный ниже код, но он генерирует фрейм данных со всеми NaN :

 df[['A1', 'B1']] = df[['A', 'B']].shift(freq=pd.DateOffset(months=1)).resample('D').last().fillna(method=ffill) df[['A_MoM', 'B_MoM']] = df[['A', 'B']].div(df[['A1', 'B1']], axis=0) - 1  

Из:

 A A1 B B1 2013-02-26 NaN NaN NaN NaN 2013-02-27 NaN NaN NaN NaN 2013-02-28 NaN NaN NaN NaN 2013-03-01 NaN NaN NaN NaN 2013-03-02 NaN NaN NaN NaN  .. .. .. .. 2013-05-22 NaN NaN NaN NaN 2013-05-23 NaN NaN NaN NaN 2013-05-24 NaN NaN NaN NaN 2013-05-25 NaN NaN NaN NaN 2013-05-26 NaN NaN NaN NaN  

How could achieve that correctly? Sincere thanks at advance.

Edit:

 df = pd.DataFrame(np.random.randint(0, 100, size=(90, 3)), index=dates, columns=['A_values', 'B_values', 'C']) df.columns  df1 = df.filter(regex='_values

Out:

 ValueError: Unable to coerce to DataFrame, shape must be (90, 2): given (93, 2)  

Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:

 df[['A1', 'B1']] = df[['A', 'B']].shift(freq=pd.DateOffset(months=1)).resample('D').last().ffill() df[['A_MoM', 'B_MoM']] = df[['A', 'B']].div(df[['A1', 'B1']].to_numpy(), axis=0) - 1 print (df)  A B C A1 B1 A_MoM B_MoM 2013-02-26 85 57 0 NaN NaN NaN NaN 2013-02-27 94 86 44 NaN NaN NaN NaN 2013-02-28 62 91 29 NaN NaN NaN NaN 2013-03-01 21 93 24 NaN NaN NaN NaN 2013-03-02 12 70 70 NaN NaN NaN NaN  .. .. .. ... ... ... ... 2013-05-22 57 13 81 14.0 50.0 3.071429 -0.740000 2013-05-23 43 68 85 2.0 45.0 20.500000 0.511111 2013-05-24 55 50 53 89.0 52.0 -0.382022 -0.038462 2013-05-25 75 78 66 86.0 54.0 -0.127907 0.444444 2013-05-26 70 93 3 4.0 45.0 16.500000 1.066667  [90 rows x 7 columns]  

Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:

 df1 = df[['A', 'B']].shift(freq=pd.DateOffset(months=1)).resample('D').last().ffill() df[['A_MoM', 'B_MoM']] = df[['A', 'B']].div(df1, axis=0) - 1 print (df)  A B C A_MoM B_MoM 2013-02-26 85 57 0 NaN NaN 2013-02-27 94 86 44 NaN NaN 2013-02-28 62 91 29 NaN NaN 2013-03-01 21 93 24 NaN NaN 2013-03-02 12 70 70 NaN NaN  .. .. .. ... ... 2013-05-22 57 13 81 3.071429 -0.740000 2013-05-23 43 68 85 20.500000 0.511111 2013-05-24 55 50 53 -0.382022 -0.038462 2013-05-25 75 78 66 -0.127907 0.444444 2013-05-26 70 93 3 16.500000 1.066667  [90 rows x 5 columns]  

EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :

 np.random.seed(2021)  dates = pd.date_range('20130226', periods=90) df = pd.DataFrame(np.random.randint(0, 100, size=(90, 3)), index=dates, columns=['A_values', 'B_values', 'C'])  df1 = df.filter(regex='_values


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon - Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).shift(freq=pd.DateOffset(months=1)).resample('D').last().ffill().add_suffix('_shifted') df2 = df.filter(regex='_valuesOut:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon - Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).div(df1.to_numpy(), axis=0) - 1 df.join(df2.add_suffix('_MoM')) Out:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon - Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).shift(freq=pd.DateOffset(months=1)).resample('D').last().ffill() print (df1.columns) Index(['A_values', 'B_values'], dtype='object') df2 = df.filter(regex='_values

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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon - Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).shift(freq=pd.DateOffset(months=1)).resample('D').last().ffill().add_suffix('_shifted') df2 = df.filter(regex='_valuesOut:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon - Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).div(df1.to_numpy(), axis=0) - 1 df.join(df2.add_suffix('_MoM')) Out:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).div(df1, axis=0).sub(1).reindex(df.index) print (df.filter(regex=’_values

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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).shift(freq=pd.DateOffset(months=1)).resample(‘D’).last().ffill().add_suffix(‘_shifted’) df2 = df.filter(regex=’_valuesOut:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).div(df1.to_numpy(), axis=0) — 1 df.join(df2.add_suffix(‘_MoM’))Out:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).columns) Index([‘A_values’, ‘B_values’], dtype=’object’) df = df.join(df2.add_suffix(‘_MoM’)) print (df) A_values B_values C A_values_MoM B_values_MoM 2013-02-26 85 57 0 NaN NaN 2013-02-27 94 86 44 NaN NaN 2013-02-28 62 91 29 NaN NaN 2013-03-01 21 93 24 NaN NaN 2013-03-02 12 70 70 NaN NaN … … .. … … 2013-05-22 57 13 81 3.071429 -0.740000 2013-05-23 43 68 85 20.500000 0.511111 2013-05-24 55 50 53 -0.382022 -0.038462 2013-05-25 75 78 66 -0.127907 0.444444 2013-05-26 70 93 3 16.500000 1.066667 [90 rows x 5 columns]

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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).shift(freq=pd.DateOffset(months=1)).resample(‘D’).last().ffill().add_suffix(‘_shifted’) df2 = df.filter(regex=’_valuesOut:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.

).div(df1.to_numpy(), axis=0) — 1 df.join(df2.add_suffix(‘_MoM’))Out:


Ответ №1:

Причина в разных именах столбцов, решение преобразуется df[['A1', 'B1']] в массив numpy:


Или , если возможно, назначьте вывод df1 , чтобы имена столбцов не менялись, чтобы можно было разделить с теми же именами столбцов, здесь A, B правильно:


EDIT: После resample того, как будет изменен также DatetimeIndex, поэтому добавлен reindex для одних и тех же индексов в обоих DataFrames :


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

1. Спасибо, еще один вопрос, поскольку в моем реальном фрейме данных много столбцов, скажем , имена столбцов ['A_values', 'B_values', 'C'] , поэтому мне нужно использовать df.filter(regex='_values$') для фильтрации первых двух столбцов , а затем использовать df.join() и add_prefix('MoM') , как я мог бы изменить ваш код? Пожалуйста, не удаляйте код, который вы опубликовали, но добавьте больше в соответствии с этим случаем.

2. @ahbon — Я думаю, что тогда .to_numpy() все должно работать хорошо.

3. Это вызывает ошибку, которую я обновил в сообщении, пожалуйста, проверьте, большое спасибо.