【问题标题】:using date range to convert month end data to weekly data on Pandas使用日期范围将月末数据转换为 Pandas 的每周数据
【发布时间】:2020-09-02 18:19:33
【问题描述】:

我有一个如下所示的数据框。是月末数据。

date ,     value , expectation
31/01/2020, 34,     40
28/02/2020, 35,     38
31/03/2020, 40,     44

我需要什么:

date ,     value , expectation

07/01/2020, 0,       0 
14/01/2020, 0,       0
21/01/2020, 0,       0
28/01/2020, 0,       0 
04/02/2020, 34,     40
11/02/2020, 0,       0
18/02/2020, 0,       0
25/02/2020, 0,       0
04/03/2020, 35,     38

基本上,我正在尝试将月末数据转换为每周数据。但是,不同的是,确切的月末日期可能与每周日期范围不匹配,因此它将落入周末日期(例如,2020 年 4 月 2 日为 2020 年 1 月 31 日)。另一个周末的日期用 0 填充。听起来很乱。但这是我尝试过的。

import pandas as pd

df = pd.read_csv('file.csv', index_col=0)
df.index = pd.to_datetime(df.index, format='%d/%m/%y')

dtr = pd.date_range('01.01.2020', '31.03.2020', freq='W')

empty = pd.DataFrame(index=dtr)

df = pd.concat([df, empty[~empty.index.isin(df.index)]]).sort_index().fillna(0)

代码有效,但我没有得到确切的预期输出。任何帮助表示赞赏。

【问题讨论】:

    标签: python pandas csv


    【解决方案1】:

    使用merge_asof:

    df.index = pd.to_datetime(df.index, format='%d/%m/%Y')
    
    dtr = pd.date_range('01.01.2020', '31.03.2020', freq='W')
    empty = pd.DataFrame(index=dtr)
    
    
    df = pd.merge_asof(empty, 
                       df, 
                       left_index=True, 
                       right_index=True, 
                       tolerance=pd.Timedelta(7, 'd')).fillna(0)
    print (df)
                value  expectation
    2020-01-05    0.0          0.0
    2020-01-12    0.0          0.0
    2020-01-19    0.0          0.0
    2020-01-26    0.0          0.0
    2020-02-02   34.0         40.0
    2020-02-09    0.0          0.0
    2020-02-16    0.0          0.0
    2020-02-23    0.0          0.0
    2020-03-01   35.0         38.0
    2020-03-08    0.0          0.0
    2020-03-15    0.0          0.0
    2020-03-22    0.0          0.0
    2020-03-29    0.0          0.0
    

    如果需要也更改周的开始,例如从星期二更改 freqdate_range

    df.index = pd.to_datetime(df.index, format='%d/%m/%Y')
    
    dtr = pd.date_range('01.01.2020', '31.03.2020', freq='W-Tue')
    empty = pd.DataFrame(index=dtr)
    
    df = pd.merge_asof(empty, 
                       df, 
                       left_index=True, 
                       right_index=True, 
                       tolerance=pd.Timedelta(7, 'd')).fillna(0)
    print (df)
                value  expectation
    2020-01-07    0.0          0.0
    2020-01-14    0.0          0.0
    2020-01-21    0.0          0.0
    2020-01-28    0.0          0.0
    2020-02-04   34.0         40.0
    2020-02-11    0.0          0.0
    2020-02-18    0.0          0.0
    2020-02-25    0.0          0.0
    2020-03-03   35.0         38.0
    2020-03-10    0.0          0.0
    2020-03-17    0.0          0.0
    2020-03-24    0.0          0.0
    2020-03-31   40.0         44.0
    

    【讨论】:

    • 我收到一个值错误。 “ValueError:必须对右键进行排序”。
    • 它给出了一个类型错误。 TypeError:无法更改对象数组的数据类型。
    • 它说 dtype:object
    • 所以 astype 不起作用。我使用了 infer_objects()。它适用于日期,但我没有得到其他列的任何值(只有 0)。代码中唯一的变化是 df = pd.read_csv('file.csv', dtype='object') df = df.infer_objects() df = df.sort_index()
    【解决方案2】:

    下面给出的一段代码会给你想要的结果:

    for end_date in df["date"]:
        days_diff = (end_date  - pd.date_range(end=end_date , freq='W', periods=5)[-1])
        pd.date_range(end='2020-03-31', freq='W', periods=5) + days_diff
    

    【讨论】:

      猜你喜欢
      • 2013-05-02
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 2015-06-19
      • 1970-01-01
      • 2020-07-06
      • 2021-04-28
      相关资源
      最近更新 更多