高级索引:我需要修改时间序列数据以回填特定时间戳的所有缺失值
Advanced Indexing: I need to munge time series data to backfill all missing values for a specific timestamp
输入二维数据:
ticker, date, time, price
AAPL, 12-04-2021, 9:45:00, 10000
AAPL, 12-04-2021, 9:51:00, 10005
AMZN, 12-04-2021, 9:46:00, 10007
AMZN, 12-04-2021, 9:52:00, 10010
期望的输出:
一个回填的分层数据框,可以通过日期、时间戳和工具进行索引,但它包含每个观察到的代码和时间戳的所有缺失时间戳的条目。此处的虚拟数据显示 AAPL 在 9:45 A.M 和 9:51 处有 2 个观察到的价格,它们不与 AMZN 的其他两个时间戳价格相交。我想做的是为每个观察到的索引创建一个时间戳条目,然后使用下一个可用时间观察来填充它。所以本质上我想要
df["12-04-2021", "9:46:00", "AAPL"]
到return10005,在9:51
的观察
df["12-04-2021", "9:45:00", "AMZN"]
到return10007,在9:46
的观察
或者通常需要将数据重组为
ticker, date, time, price
AAPL, 12-04-2021, 9:45:00, 10000
AAPL, 12-04-2021, 9:46:00, 10005
AAPL, 12-04-2021, 9:51:00, 10005
AAPL, 12-04-2021, 9:52:00, 10005 [Should be the next available value in time possible]
AMZN, 12-04-2021, 9:45:00, 10007
AMZN, 12-04-2021, 9:46:00, 10007
AMZN, 12-04-2021, 9:51:00, 10010
AMZN, 12-04-2021, 9:52:00, 10010
这是样本虚拟数据,但通常在市场交易时间内的时间戳范围内会有更多的日期和代码,我考虑过是应该先执行回填还是索引数据帧然后回填。我想我需要从根本上了解如何设置数据帧,以便为丢失的时间戳分配 NA 值,因为无论我现在尝试什么,都会给我一个 KeyError 而不是 NA 值。
我试过了
df = pd.read_csv(`DATA`, index_col=['date', 'time', 'ticker'])
df = df.stack(dropna=False)
df.update(df.groupby(['date', 'time', 'ticker']).bfill())
但我认为我并没有从根本上理解如何将 [date,time] 列指定为通用字段,该字段必须具有观测值或 NA 才能开始回填。对于我尝试过的大多数组合,我都遇到了关键错误。
任何关于如何理解这一点的想法将不胜感激,如果你一路走到这里,谢谢。
我建议将 date
和 time
s 转换为日期时间,然后按 Series.unstack
with backfilling and forward filling missing values and then reshape back by DataFrame.stack
:
重塑
df['datetimes'] = pd.to_datetime(df.pop('date') + ' ' + df.pop('time'))
df = (df.set_index(['ticker','datetimes'])['price']
.unstack()
.bfill(axis=1)
.ffill(axis=1)
.stack()
.reset_index(name='col2'))
print (df)
ticker datetimes col2
0 AAPL 2021-12-04 09:45:00 10000.0
1 AAPL 2021-12-04 09:46:00 10005.0
2 AAPL 2021-12-04 09:51:00 10005.0
3 AAPL 2021-12-04 09:52:00 10005.0
4 AMZN 2021-12-04 09:45:00 10007.0
5 AMZN 2021-12-04 09:46:00 10007.0
6 AMZN 2021-12-04 09:51:00 10010.0
7 AMZN 2021-12-04 09:52:00 10010.0
df['date'] = df['datetimes'].dt.date
df['time'] = df['datetimes'].dt.time
print (df)
ticker datetimes col2 date time
0 AAPL 2021-12-04 09:45:00 10000.0 2021-12-04 09:45:00
1 AAPL 2021-12-04 09:46:00 10005.0 2021-12-04 09:46:00
2 AAPL 2021-12-04 09:51:00 10005.0 2021-12-04 09:51:00
3 AAPL 2021-12-04 09:52:00 10005.0 2021-12-04 09:52:00
4 AMZN 2021-12-04 09:45:00 10007.0 2021-12-04 09:45:00
5 AMZN 2021-12-04 09:46:00 10007.0 2021-12-04 09:46:00
6 AMZN 2021-12-04 09:51:00 10010.0 2021-12-04 09:51:00
7 AMZN 2021-12-04 09:52:00 10010.0 2021-12-04 09:52:00
使用 GroupBy.apply
和 lambda 函数的解决方案:
df['datetimes'] = pd.to_datetime(df.pop('date') + ' ' + df.pop('time'))
dates = df['datetimes'].drop_duplicates().sort_values()
f = lambda x: x.reindex(dates, method='bfill').ffill()
df = (df.set_index('datetimes').groupby(['ticker'])['price'].apply(f)
.reset_index(name='col2')
)
print (df)
ticker datetimes col2
0 AAPL 2021-12-04 09:45:00 10000.0
1 AAPL 2021-12-04 09:46:00 10005.0
2 AAPL 2021-12-04 09:51:00 10005.0
3 AAPL 2021-12-04 09:52:00 10005.0
4 AMZN 2021-12-04 09:45:00 10007.0
5 AMZN 2021-12-04 09:46:00 10007.0
6 AMZN 2021-12-04 09:51:00 10010.0
7 AMZN 2021-12-04 09:52:00 10010.0
输入二维数据:
ticker, date, time, price
AAPL, 12-04-2021, 9:45:00, 10000
AAPL, 12-04-2021, 9:51:00, 10005
AMZN, 12-04-2021, 9:46:00, 10007
AMZN, 12-04-2021, 9:52:00, 10010
期望的输出:
一个回填的分层数据框,可以通过日期、时间戳和工具进行索引,但它包含每个观察到的代码和时间戳的所有缺失时间戳的条目。此处的虚拟数据显示 AAPL 在 9:45 A.M 和 9:51 处有 2 个观察到的价格,它们不与 AMZN 的其他两个时间戳价格相交。我想做的是为每个观察到的索引创建一个时间戳条目,然后使用下一个可用时间观察来填充它。所以本质上我想要
df["12-04-2021", "9:46:00", "AAPL"]
到return10005,在9:51
df["12-04-2021", "9:45:00", "AMZN"]
到return10007,在9:46
或者通常需要将数据重组为
ticker, date, time, price
AAPL, 12-04-2021, 9:45:00, 10000
AAPL, 12-04-2021, 9:46:00, 10005
AAPL, 12-04-2021, 9:51:00, 10005
AAPL, 12-04-2021, 9:52:00, 10005 [Should be the next available value in time possible]
AMZN, 12-04-2021, 9:45:00, 10007
AMZN, 12-04-2021, 9:46:00, 10007
AMZN, 12-04-2021, 9:51:00, 10010
AMZN, 12-04-2021, 9:52:00, 10010
这是样本虚拟数据,但通常在市场交易时间内的时间戳范围内会有更多的日期和代码,我考虑过是应该先执行回填还是索引数据帧然后回填。我想我需要从根本上了解如何设置数据帧,以便为丢失的时间戳分配 NA 值,因为无论我现在尝试什么,都会给我一个 KeyError 而不是 NA 值。
我试过了
df = pd.read_csv(`DATA`, index_col=['date', 'time', 'ticker'])
df = df.stack(dropna=False)
df.update(df.groupby(['date', 'time', 'ticker']).bfill())
但我认为我并没有从根本上理解如何将 [date,time] 列指定为通用字段,该字段必须具有观测值或 NA 才能开始回填。对于我尝试过的大多数组合,我都遇到了关键错误。
任何关于如何理解这一点的想法将不胜感激,如果你一路走到这里,谢谢。
我建议将 date
和 time
s 转换为日期时间,然后按 Series.unstack
with backfilling and forward filling missing values and then reshape back by DataFrame.stack
:
df['datetimes'] = pd.to_datetime(df.pop('date') + ' ' + df.pop('time'))
df = (df.set_index(['ticker','datetimes'])['price']
.unstack()
.bfill(axis=1)
.ffill(axis=1)
.stack()
.reset_index(name='col2'))
print (df)
ticker datetimes col2
0 AAPL 2021-12-04 09:45:00 10000.0
1 AAPL 2021-12-04 09:46:00 10005.0
2 AAPL 2021-12-04 09:51:00 10005.0
3 AAPL 2021-12-04 09:52:00 10005.0
4 AMZN 2021-12-04 09:45:00 10007.0
5 AMZN 2021-12-04 09:46:00 10007.0
6 AMZN 2021-12-04 09:51:00 10010.0
7 AMZN 2021-12-04 09:52:00 10010.0
df['date'] = df['datetimes'].dt.date
df['time'] = df['datetimes'].dt.time
print (df)
ticker datetimes col2 date time
0 AAPL 2021-12-04 09:45:00 10000.0 2021-12-04 09:45:00
1 AAPL 2021-12-04 09:46:00 10005.0 2021-12-04 09:46:00
2 AAPL 2021-12-04 09:51:00 10005.0 2021-12-04 09:51:00
3 AAPL 2021-12-04 09:52:00 10005.0 2021-12-04 09:52:00
4 AMZN 2021-12-04 09:45:00 10007.0 2021-12-04 09:45:00
5 AMZN 2021-12-04 09:46:00 10007.0 2021-12-04 09:46:00
6 AMZN 2021-12-04 09:51:00 10010.0 2021-12-04 09:51:00
7 AMZN 2021-12-04 09:52:00 10010.0 2021-12-04 09:52:00
使用 GroupBy.apply
和 lambda 函数的解决方案:
df['datetimes'] = pd.to_datetime(df.pop('date') + ' ' + df.pop('time'))
dates = df['datetimes'].drop_duplicates().sort_values()
f = lambda x: x.reindex(dates, method='bfill').ffill()
df = (df.set_index('datetimes').groupby(['ticker'])['price'].apply(f)
.reset_index(name='col2')
)
print (df)
ticker datetimes col2
0 AAPL 2021-12-04 09:45:00 10000.0
1 AAPL 2021-12-04 09:46:00 10005.0
2 AAPL 2021-12-04 09:51:00 10005.0
3 AAPL 2021-12-04 09:52:00 10005.0
4 AMZN 2021-12-04 09:45:00 10007.0
5 AMZN 2021-12-04 09:46:00 10007.0
6 AMZN 2021-12-04 09:51:00 10010.0
7 AMZN 2021-12-04 09:52:00 10010.0