【发布时间】:2021-12-22 22:35:12
【问题描述】:
假设我有如下的每日数据:
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变化,例如@987654325的每月pct变化值 @ for 2013-05-26 的计算方法是:A 在 2013-05-26 的值除以 2013-04-26 的值减去 1。
我的想法是这样的:通过将它们向前移动一个月来创建新列'A1', 'B1',然后df['A_MoM']将由df['A']/df['A_shifted'] - 1计算,与列B的逻辑相同。
由于并非所有月份的天数都相同,所以我将使用上个月的最后一天的值,即计算 2013-03-30 的 pct 变化将通过以下方式计算:2013-03-30's value/2013-02-28's value - 1。
我尝试了下面的代码,但它生成了一个包含所有NaNs 的数据框:
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
如何正确实现这一点?提前致以诚挚的感谢。
编辑:
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$').shift(freq=pd.DateOffset(months=1)).resample('D').last().ffill().add_suffix('_shifted')
df2 = df.filter(regex='_values$').div(df1.to_numpy(), axis=0) - 1
df.join(df2.add_suffix('_MoM'))
输出:
ValueError: Unable to coerce to DataFrame, shape must be (90, 2): given (93, 2)
【问题讨论】:
标签: python-3.x pandas dataframe numpy date