【问题标题】:Pandas loop over custom dates (month year) to (month year+N) for plottingPandas 将自定义日期(月年)循环到(月年+N)以进行绘图
【发布时间】:2017-05-06 15:04:49
【问题描述】:

我一直在分析运行了几个月的数据,然后每月生成并保存一个数字。到目前为止,当这些都在同一日历年内时,这非常有效,但我不知道当数据跨越到下一年时如何指示循环工作。

示例代码:

import pandas as pd
import datetime as datetime
import matplotlib as plt

df = pd.read_csv("file.csv")
df.index = df.Datetime

for month in range(4,12): #Data starts in April in this example
    fig, axes = plt.subplots(nrows=2,ncols=1, sharex=True, figsize =(18,10))
    startDate = datetime.date(2016,month,1)
    stopDate = datetime.date(2016,month+1,1)
    date_val = startDate.strftime("%B %Y")

    k=0
    df.PRe[startDate:stopDate].plot(ax=axes[k])
    #ylim, xlim, title etc
    k=1
    df.PRp[startDate:stopDate].plot(ax=axes[k])

    plt.savefig("PRe and PRp in %s.png"%date_val,bbox_inches="tight")

This SO question 接近了,尽管他们使用 pandas datetime 对象而不是我使用的 datetime.date 对象。我是否应该修改我的代码以适应解决方案,如果是,如何? 否则,一旦我们超过 2016 年,是否有一种 pandas/pythonic 的方法可以让它工作 - 无论是对于已知的开始和结束日期,还是更好,对于任何开始和结束日期?

【问题讨论】:

    标签: python datetime pandas matplotlib


    【解决方案1】:

    你可以使用dateoffset:

    month = 4
    startDate = datetime.date(2016,month,1)
    print (startDate)
    stopDate = (startDate + pd.offsets.MonthBegin()).date()
    print (stopDate)
    2016-04-01
    2016-05-01
    

    month = 4
    startDate = datetime.date(2016,month,1)
    print (startDate)
    stopDate = (startDate + pd.offsets.DateOffset(months=1)).date()
    print (stopDate)
    2016-04-01
    2016-05-01
    

    另一个解决方案是datetimeindex partial string indexing,如果需要选择yearmonth

    df.PRe['2016-4'].plot(ax=axes[k])
    

    df.PRe[str(2016)+'-'+str(month)].plot(ax=axes[k])
    

    如果需要在datetimeindex 中循环的解决方案按唯一的年份和月份按唯一的month 周期按DatetimeIndex.to_period

    start = pd.to_datetime('2015-10-24')
    rng = pd.date_range(start, periods=10, freq='3W')
    
    df = pd.DataFrame({'PRe': np.random.randint(10, size=10)}, index=rng)  
    print (df)
                PRe
    2015-10-25    2
    2015-11-15    3
    2015-12-06    3
    2015-12-27    1
    2016-01-17    8
    2016-02-07    4
    2016-02-28    2
    2016-03-20    6
    2016-04-10    8
    2016-05-01    0
    2015-10-25    2
    
    for date in df.index.to_period('m').unique():
        print (df.PRe[str(date)])
    
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2015-11-15    3
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2015-12-06    3
    2015-12-27    1
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2016-01-17    8
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2016-02-07    4
    2016-02-28    2
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2016-03-20    6
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2016-04-10    8
    Freq: 3W-SUN, Name: PRe, dtype: int32
    2016-05-01    0
    Freq: 3W-SUN, Name: PRe, dtype: int32
    

    【讨论】:

    • 请问DatetimeIndex.to_period(DatetimeIndex.to_pydatetime) 函数是否适用于my question?谢谢
    【解决方案2】:

    @jezrael 的回答解决了这个问题;以下是后代的解决方案。

    import pandas as pd
    import matplotlib as plt
    
    df = pd.read_csv("file.csv")
    df.index = df.Datetime
    
    startDate = df.index[0] #seed the while loop, format Timestamp
    while (startDate >= df.index[0]) & (startDate < df.index[-1]): 
        fig, axes = plt.subplots(nrows=2,ncols=1, sharex=True, figsize =(18,10))
    
        stopDate = (startDate + pd.offsets.MonthBegin())#stopDate also Timestamp
        date_val = startDate.strftime("%B %Y")#Date as Month Year string
    
        k=0
        df.PRe[startDate:stopDate].plot(ax=axes[k])
        #ylim, xlim, title etc
        k=1
        df.PRp[startDate:stopDate].plot(ax=axes[k])
        #ylim, xlim, title etc
        plt.savefig("PRe and PRp in %s.png"%date_val,bbox_inches="tight")
        startDate = stopDate
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      相关资源
      最近更新 更多