pandas 重新索引缺失日期
pandas re-indexing with missing dates
from dateutil.rrule import rrule, MONTHLY
def fread_year_month(strt_dt, end_dt):
dates = [dt for dt in rrule(MONTHLY, dtstart=strt_dt, until=end_dt)]
return dates
df = pd.DataFrame({
'value' : [4,2,5,6,7,8,6,5,4,1,2,4],
'date': fread_year_month(dt.datetime(2015, 1, 1),dt.datetime(2015, 12, 1)),
'stock': ['amzn']*12
},columns=[
'value', 'date', 'stock'] )
df2 = pd.DataFrame({
'value' : [1,1,1,1,1],
'date': fread_year_month(dt.datetime(2015, 1, 1),dt.datetime(2015, 5, 1)),
'stock': ['msft']*5
},columns=[
'value', 'date', 'stock'] )
df = df.append(df2)
df.set_index(['stock', 'date'], inplace=True)
我有上面的 pandas 数据框。如您所见,amzn 的可用数据数量与 msft 不同。在此示例中,日期是连续的,但不必如此(日期可以是任何日期)。
如果可用日期的范围是我拥有 AMZN 数据的日期,那么我如何为我的数据框中的所有其他股票添加这些确切日期,其中包含 NaN 或 NA。
在示例中,我想在索引中插入 msft 缺失的日期,并为这些日期索引的值插入 NaN 或 NA。
如果您想将代码作为列使用,可以执行 unstack
,如下所示:
In [71]: df.unstack(level=0)
Out[71]:
value
stock amzn msft
date
2015-01-01 4.0 1.0
2015-02-01 2.0 1.0
2015-03-01 5.0 1.0
2015-04-01 6.0 1.0
2015-05-01 7.0 1.0
2015-06-01 8.0 NaN
2015-07-01 6.0 NaN
2015-08-01 5.0 NaN
2015-09-01 4.0 NaN
2015-10-01 1.0 NaN
2015-11-01 2.0 NaN
2015-12-01 4.0 NaN
为了重新索引到相同的形状,下面的 from_product
创建了一个新的 MultiIndex
,其中包含日期/代码的所有组合。
In [75]: df.reindex(pd.MultiIndex.from_product(df.index.levels))
Out[75]:
value
amzn 2015-01-01 4.0
2015-02-01 2.0
2015-03-01 5.0
2015-04-01 6.0
2015-05-01 7.0
2015-06-01 8.0
2015-07-01 6.0
2015-08-01 5.0
2015-09-01 4.0
2015-10-01 1.0
2015-11-01 2.0
2015-12-01 4.0
msft 2015-01-01 1.0
2015-02-01 1.0
2015-03-01 1.0
2015-04-01 1.0
2015-05-01 1.0
2015-06-01 NaN
2015-07-01 NaN
2015-08-01 NaN
2015-09-01 NaN
2015-10-01 NaN
2015-11-01 NaN
2015-12-01 NaN
在合并之前,您可以这样做(从 Pandas 0.17 开始):
>>> df2.set_index('date').reindex(df.date)
value stock
date
2015-01-01 1 msft
2015-02-01 1 msft
2015-03-01 1 msft
2015-04-01 1 msft
2015-05-01 1 msft
2015-06-01 NaN NaN
2015-07-01 NaN NaN
2015-08-01 NaN NaN
2015-09-01 NaN NaN
2015-10-01 NaN NaN
2015-11-01 NaN NaN
2015-12-01 NaN NaN
from dateutil.rrule import rrule, MONTHLY
def fread_year_month(strt_dt, end_dt):
dates = [dt for dt in rrule(MONTHLY, dtstart=strt_dt, until=end_dt)]
return dates
df = pd.DataFrame({
'value' : [4,2,5,6,7,8,6,5,4,1,2,4],
'date': fread_year_month(dt.datetime(2015, 1, 1),dt.datetime(2015, 12, 1)),
'stock': ['amzn']*12
},columns=[
'value', 'date', 'stock'] )
df2 = pd.DataFrame({
'value' : [1,1,1,1,1],
'date': fread_year_month(dt.datetime(2015, 1, 1),dt.datetime(2015, 5, 1)),
'stock': ['msft']*5
},columns=[
'value', 'date', 'stock'] )
df = df.append(df2)
df.set_index(['stock', 'date'], inplace=True)
我有上面的 pandas 数据框。如您所见,amzn 的可用数据数量与 msft 不同。在此示例中,日期是连续的,但不必如此(日期可以是任何日期)。
如果可用日期的范围是我拥有 AMZN 数据的日期,那么我如何为我的数据框中的所有其他股票添加这些确切日期,其中包含 NaN 或 NA。
在示例中,我想在索引中插入 msft 缺失的日期,并为这些日期索引的值插入 NaN 或 NA。
如果您想将代码作为列使用,可以执行 unstack
,如下所示:
In [71]: df.unstack(level=0)
Out[71]:
value
stock amzn msft
date
2015-01-01 4.0 1.0
2015-02-01 2.0 1.0
2015-03-01 5.0 1.0
2015-04-01 6.0 1.0
2015-05-01 7.0 1.0
2015-06-01 8.0 NaN
2015-07-01 6.0 NaN
2015-08-01 5.0 NaN
2015-09-01 4.0 NaN
2015-10-01 1.0 NaN
2015-11-01 2.0 NaN
2015-12-01 4.0 NaN
为了重新索引到相同的形状,下面的 from_product
创建了一个新的 MultiIndex
,其中包含日期/代码的所有组合。
In [75]: df.reindex(pd.MultiIndex.from_product(df.index.levels))
Out[75]:
value
amzn 2015-01-01 4.0
2015-02-01 2.0
2015-03-01 5.0
2015-04-01 6.0
2015-05-01 7.0
2015-06-01 8.0
2015-07-01 6.0
2015-08-01 5.0
2015-09-01 4.0
2015-10-01 1.0
2015-11-01 2.0
2015-12-01 4.0
msft 2015-01-01 1.0
2015-02-01 1.0
2015-03-01 1.0
2015-04-01 1.0
2015-05-01 1.0
2015-06-01 NaN
2015-07-01 NaN
2015-08-01 NaN
2015-09-01 NaN
2015-10-01 NaN
2015-11-01 NaN
2015-12-01 NaN
在合并之前,您可以这样做(从 Pandas 0.17 开始):
>>> df2.set_index('date').reindex(df.date)
value stock
date
2015-01-01 1 msft
2015-02-01 1 msft
2015-03-01 1 msft
2015-04-01 1 msft
2015-05-01 1 msft
2015-06-01 NaN NaN
2015-07-01 NaN NaN
2015-08-01 NaN NaN
2015-09-01 NaN NaN
2015-10-01 NaN NaN
2015-11-01 NaN NaN
2015-12-01 NaN NaN