将缺失的日期添加到熊猫数据框中
我的数据可能在给定日期有多个事件,或者在某个日期没有事件。我采取这些事件,按日期计算并绘制它们。但是,当我绘制它们时,我的两个系列并不总是匹配。将缺失的日期添加到熊猫数据框中
idx = pd.date_range(df['simpleDate'].min(), df['simpleDate'].max())
s = df.groupby(['simpleDate']).size()
在上面的代码IDX成为范围的说30个日期。 09-01-2013至09-30-2013 但是S可能只有25或26天,因为在给定日期没有发生任何事件。然后我得到一个AssertionError的尺寸不匹配时,我尝试绘图:
fig, ax = plt.subplots()
ax.bar(idx.to_pydatetime(), s, color='green')
什么来解决这个正确的方法是什么?我想从IDX或(我宁愿这样做)中删除没有数值的日期,并将计数为0的日期添加到系列中。我宁愿使用0值的30天完整图表。如果这种方法是正确的,有关如何开始的任何建议?我需要某种动态reindex
功能吗?
这里的小号(df.groupby(['simpleDate']).size()
)的片段,发现没有条目04和05
09-02-2013 2
09-03-2013 10
09-06-2013 5
09-07-2013 1
你可以使用Series.reindex
:
import pandas as pd
idx = pd.date_range('09-01-2013', '09-30-2013')
s = pd.Series({'09-02-2013': 2,
'09-03-2013': 10,
'09-06-2013': 5,
'09-07-2013': 1})
s.index = pd.DatetimeIndex(s.index)
s = s.reindex(idx, fill_value=0)
print(s)
产量
2013-09-01 0
2013-09-02 2
2013-09-03 10
2013-09-04 0
2013-09-05 0
2013-09-06 5
2013-09-07 1
2013-09-08 0
...
这里有一个很好的方法来填补缺失的日期一个数据帧,与您选择的fill_value
,days_back
填写和排序顺序(date_order
)通过排序数据框:
def fill_in_missing_dates(df, date_col_name = 'date',date_order = 'asc', fill_value = 0, days_back = 30):
df.set_index(date_col_name,drop=True,inplace=True)
df.index = pd.DatetimeIndex(df.index)
d = datetime.now().date()
d2 = d - timedelta(days = days_back)
idx = pd.date_range(d2, d, freq = "D")
df = df.reindex(idx,fill_value=fill_value)
df[date_col_name] = pd.DatetimeIndex(df.index)
return df
的一个问题是,如果有重复的值reindex
将失败。说我们有时间戳的数据,我们按日期要索引工作:
df = pd.DataFrame({
'timestamps': pd.to_datetime(
['2016-11-15 1:00','2016-11-16 2:00','2016-11-16 3:00','2016-11-18 4:00']),
'values':['a','b','c','d']})
df.index = pd.DatetimeIndex(df['timestamps']).floor('D')
df
产生
timestamps values
2016-11-15 "2016-11-15 01:00:00" a
2016-11-16 "2016-11-16 02:00:00" b
2016-11-16 "2016-11-16 03:00:00" c
2016-11-18 "2016-11-18 04:00:00" d
由于重复2016-11-16
日期,企图重新索引:
all_days = pd.date_range(df.index.min(), df.index.max(), freq='D')
df.reindex(all_days)
失败:
...
ValueError: cannot reindex from a duplicate axis
(这个就意味着指数有重复,不在于它本身是一个DUP)
相反,我们可以使用.loc
查找条目的所有日期的范围:
df.loc[all_days]
产量
timestamps values
2016-11-15 "2016-11-15 01:00:00" a
2016-11-16 "2016-11-16 02:00:00" b
2016-11-16 "2016-11-16 03:00:00" c
2016-11-17 NaN NaN
2016-11-18 "2016-11-18 04:00:00" d
fillna
可用于色谱柱系列填充空白(如果需要)。
更快的解决方法是使用asfreq()
。这并不需要创建新的索引到用户中reindex()
调用。*
dates = pd.Index([pd.Timestamp('2012-05-01'),
pd.Timestamp('2012-05-04'),
pd.Timestamp('2012-05-06')])
s = pd.Series([1, 2, 3], dates)
print(s.asfreq('D'))
2012-05-01 1.0
2012-05-02 NaN
2012-05-03 NaN
2012-05-04 2.0
2012-05-05 NaN
2012-05-06 3.0
Freq: D, dtype: float64
*至少不是。这很好,可以在引擎盖下调用。
在很多情况下,resample
(see documentation here)提供了一个通用的解决方案,可以处理缺失日期和重复日期。例如:
df.resample('D').mean()
resample
是延迟操作像groupby
所以你需要使用另一个操作遵循它。在这情况下mean
效果很好,但你也可以使用许多标准的大熊猫方法有像max
,sum
等
这里是原始数据,但与“2013年9月3日”额外的条目:
val
date
2013-09-02 2
2013-09-03 10
2013-09-03 20
2013-09-06 5
2013-09-07 1
而且这里的结果:
val
date
2013-09-02 2.0
2013-09-03 15.0 <- mean of original values for 2013-09-03
2013-09-04 NaN <- NaN b/c date not present in orig
2013-09-05 NaN <- NaN b/c date not present in orig
2013-09-06 5.0
2013-09-07 1.0
注意,在此之后,你可以使用像fillna
或interpolate
方法根据需要来填补缺失值。
哇谢谢!我并不完全了解重建索引的效果。 – KHibma
'reindex'是一个了不起的功能。它可以(1)重新排序现有数据以匹配一组新标签,(2)插入之前没有标签的新行,(3)填充丢失标签的数据(包括前向/后向填充)(4)选择行按标签! – unutbu
@unutbu这回答我也有一个问题的一部分,谢谢!但是想知道你是否知道如何动态地创建包含事件日期的列表? –