pandas 周数据如何计算同比数据?

3qpi33ja  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(133)

以链接中的 * 周度经济指数(Lewis-Mertens-Stock)* 数据为例(点击this page上的 * 下载 * 按钮下载),我希望计算出同比的周度数据,但一年中并不正好有52周。
这里的主要问题是,有些年份大多有52周,而例如,2015年和2020年有53周。我希望用2014年和2019年的第52周来计算2015年和2020年第53周的同比数据,以处理这两年周与周之间不一致的问题。
如何编写一个周同比计算函数,用前一年第53周和第52周的数据计算出今年的同比对比?当然,如果有其他方法来计算每周的同比计算,也欢迎提出建议。谢谢.
我的代码:

import pandas as pd

df = pd.read_excel('../raw_data/WEI.xls', skiprows=10)
df['observation_date'] = pd.to_datetime(df['observation_date'])
df

def add_date_parts(df, date_column):
     # df['year_week_ori'] = df[date_column].dt.strftime('%Y-%U')
     df['year_week_ori'] = df[date_column].dt.strftime('%Y-%V')
     df['year'] = df[date_column].dt.isocalendar().year
     df['week'] = df[date_column].dt.isocalendar().week
     # df['year_week_ori'] = df['year'].astype(str) + '-' + df['week'].astype(str).str.zfill(2)
     df.loc[df['week'] > 52, 'week'] = 52
     df['year_week_modified'] = df['year'].astype(str) + '-' + df['week'].astype(str).str.zfill(2)
     df['year'] = df[date_column].dt.year
     df['month'] = df[date_column].dt.month
     return df
df = add_date_parts(df, 'observation_date')
df

输出:

observation_date   WEI year_week_ori  year  week year_week_modified  month
0         2008-01-05  1.80       2008-01  2008     1            2008-01      1
1         2008-01-12  1.78       2008-02  2008     2            2008-02      1
2         2008-01-19  1.75       2008-03  2008     3            2008-03      1
3         2008-01-26  1.28       2008-04  2008     4            2008-04      1
4         2008-02-02  0.99       2008-05  2008     5            2008-05      2
..               ...   ...           ...   ...   ...                ...    ...
817       2023-09-02  1.72       2023-35  2023    35            2023-35      9
818       2023-09-09  1.72       2023-36  2023    36            2023-36      9
819       2023-09-16  2.17       2023-37  2023    37            2023-37      9
820       2023-09-23  1.62       2023-38  2023    38            2023-38      9
821       2023-09-30  1.83       2023-39  2023    39            2023-39      9
[822 rows x 7 columns]

通过检查每年的周数量,我们可以看到在2011年,2016年和2022年,我们有53周的数据:

df.groupby('year')['WEI'].count()
Out[61]: 
year
2008    52
2009    52
2010    52
2011    53
2012    52
2013    52
2014    52
2015    52
2016    53
2017    52
2018    52
2019    52
2020    52
2021    52
2022    53
2023    39

我的函数(它还不能解决连续几年每周数量不能对齐的问题):

def calculate_week_on_week(df, value_column, date_column):
    df = df.sort_values(date_column)
    df['value_last_year'] = df[value_column].shift(52)
    df['week_on_week'] = (df[value_column] - df['value_last_year'])/df['value_last_year']
    return df
erhoui1w

erhoui1w1#

示例

为了解决这个问题,我们需要a minimal and reproducible example。在你的例子中,我删除了不必要的列,并创建了一个直到第二周才存在的世界。

import pandas as pd
data = {'date': ['2008-01-05', '2008-01-12', '2009-01-03', '2009-01-10', '2009-01-17'], 
        'WEI': [10, 20, 18, 14, 16], 
        'year': [2008, 2008, 2009, 2009, 2009], 'week': [1, 2, 1, 2, 3]}
df = pd.DataFrame(data)

DF

date        WEI year    week
0   2008-01-05  10  2008    1
1   2008-01-12  20  2008    2
2   2009-01-03  18  2009    1
3   2009-01-10  14  2009    2
4   2009-01-17  16  2009    3

验证码

大多数年份以2周结束(如2008年),但3年以3周结束(如2009年)。返回年变化率,但将2009年的第3周与2008年的第2周进行比较。

n = 3
s1 = df.groupby('week')['WEI'].pct_change()
cond = df['week'] == n
s1.mask(cond, df['WEI'].pct_change(n))

产出:

0    NaN
1    NaN
2    0.8
3   -0.3
4   -0.2

第一周和第二周的数据按周分组,并与前一年的相应周进行比较。对于第三周,通过与上面三行的值进行比较来计算变化率。
现在输出到change

df.assign(change=s1.mask(cond, df['WEI'].pct_change(n)))

产出:

date        WEI year    week    change
0   2008-01-05  10  2008    1       NaN
1   2008-01-12  20  2008    2       NaN
2   2009-01-03  18  2009    1       0.8    <- compare with 10
3   2009-01-10  14  2009    2       -0.3   <- compare with 20
4   2009-01-17  16  2009    3       -0.2   <- compare with 20

当应用到你的数据集时,用53替换n以匹配你的例子。

xdyibdwo

xdyibdwo2#

我建议一个更简单的方法。而不是试图匹配几年之间的周数,计算52周滞后而不是1年滞后的百分比变化。这将是7 * 52 = 364天,这只是一天的错误,或在闰年的两天。
首先,由于WEI位于FRED上,因此可以使用Pandas Datareader加载它。

import pandas_datareader as pdr
import pandas as pd
import datetime
start = datetime.datetime (2008, 1, 1)
wei_series = pdr.get_data_fred('WEI', start)

接下来,您可以对pct_change()使用periods参数,这将更改要回看的周期数以计算更改。

wei_series_pct = wei_series.pct_change(52).dropna() * 100
print(wei_series_pct)

就是这样
旁注:由于您使用的数据集过零,计算百分比变化有点奇怪。

这是2021-02-27和2022-02-26之间的12,000%增长,这是因为WEI在此期间从0.04上升到4.96。

相关问题