Pandas 将自定义日期(月年)循环到(月年+N)以进行绘图
Posted
技术标签:
【中文标题】Pandas 将自定义日期(月年)循环到(月年+N)以进行绘图【英文标题】:Pandas loop over custom dates (month year) to (month year+N) for plotting 【发布时间】: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 的方法可以让它工作 - 无论是对于已知的开始和结束日期,还是更好,对于任何开始和结束日期?
【问题讨论】:
【参考方案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,如果需要选择year
和month
:
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
【讨论】:
以上是关于Pandas 将自定义日期(月年)循环到(月年+N)以进行绘图的主要内容,如果未能解决你的问题,请参考以下文章