pandas 在特定时间(不是午夜)将数据帧规范化为数据(报价)
pandas Normalize dataframe to data (quotes) at specific time (not midnight)
我在数据框 (ds) 中有每天的数据,看起来像这样跨越了几年:
对于每一天,我都需要将所有报价标准化为该特定日期的特定时间。例如,6月1日,我需要将所有报价标准化为6月1日下午3点的报价,但在6月2日,我需要将它们全部标准化为6月2日下午3点的报价。
我有一个包含每天下午 3 点所有报价的数据框,如下所示:
所以我认为如果我可以简单地将我的报价数据帧 (ds) 除以下午 3 点数据帧就可以了:
dr = ds.groupby(ds.index.date).apply(lambda x: x / b)
值得注意的是,下午 3 点的数据框比报价数据框 (ds) 多 天。 因此,报价数据框将必须在 3pm 数据框中划分正确的相应日期,可能使用 b.index.date
我也尝试过不使用单独的数据框,而是从报价数据框 (ds) 本身中提取最后一个可用的报价 - 这也不起作用:
编辑:感谢 DSM 的建议。这有帮助吗?不确定我是否应该 pd.to_string() 数据框,因为它似乎也不容易被剪贴板读取。
引用 ds 数据帧:
bid ask mid
2000-01-04 14:45:12+00:00 281.0 281.5 281.25
2000-01-04 14:46:10+00:00 281.0 282.0 281.5
2000-01-04 14:47:14+00:00 281.2 282.2 281.7
2000-01-04 14:47:22+00:00 281.25 281.85 281.55
2000-01-04 14:47:47+00:00 281.25 281.75 281.5
2000-01-04 14:48:09+00:00 281.4 281.9 281.65
2000-01-04 14:48:40+00:00 281.3 282.3 281.8
2000-01-04 14:49:40+00:00 281.3 281.8 281.55
2000-01-04 14:49:45+00:00 281.2 282.2 281.7
2000-01-04 14:50:53+00:00 281.4 281.9 281.65
3pm 数据帧:
bid_close ask_close price
2000-01-04 15:00:00+00:00 281.35 281.95 281.65
2000-01-05 15:00:00+00:00 280.73 281.48 281.105
2000-01-06 15:00:00+00:00 279.7 280.3 280.0
2000-01-07 15:00:00+00:00 282.3 282.9 282.6
2000-01-10 15:00:00+00:00 281.7 282.3 282.0
2000-01-11 15:00:00+00:00 282.1 282.7 282.4
2000-01-12 15:00:00+00:00 281.9 282.5 282.2
2000-01-13 15:00:00+00:00 281.9 282.7 282.3
2000-01-14 15:00:00+00:00 283.15 283.75 283.45
2000-01-17 15:00:00+00:00 285.5 286.0 285.75
和命令:
c = ds.groupby(ds.index.date).apply(lambda x: x / x.between_time('14:30:00', '14:59:59').resample('30Min', how='last').dropna(how='all'))
我也试过了(看起来很接近):
df = a.groupby(a.index.date).apply(lambda x: x / x.between_time('14:45:00', '14:59:59').tail(1))
这是一个似乎相关的 link(以及我基于上面命令的内容):Grouping daily data by month in python/pandas and then normalizing
这是第一天的简化示例,考虑到 d 是您的 quotes ds dataframe 和 n 是您的 3pm 数据帧:
#get the first day of the 3pm dataframe
first_day = n.index.levels[0][0]
#get the day of the quotes dataframe from the first day of 3pm frame
d1 = d.ix[first_day]
#get the 3pm values for the first day
n1 = n.ix[first_day]
#normalize the bid column, don't forget to modify the range variable
norm = pd.concat([d1[d1.columns[i]].apply(lambda x: x / n1[n1.columns[i]]) for i in range(3)], axis = 1)
>>> norm
15:00:00+00:00 15:00:00+00:00 15:00:00+00:00
14:45:12+00:00 0.9987559978674249 0.9984039723355205 0.9985797976211611
14:46:10+00:00 0.9987559978674249 1.0001773364071644 0.9994674241079354
14:47:14+00:00 0.9994668562288963 1.000886682035822 1.0001775252973548
14:47:22+00:00 0.9996445708192642 0.9996453271856713 0.9996449494052904
14:47:47+00:00 0.9996445708192642 0.9992906543713425 0.9994674241079354
14:48:09+00:00 1.0001777145903676 0.9998226635928356 1.0
14:48:40+00:00 0.9998222854096321 1.0012413548501509 1.0005325758920647
14:49:40+00:00 0.9998222854096321 0.9994679907785069 0.9996449494052904
14:49:45+00:00 0.9994668562288963 1.000886682035822 1.0001775252973548
14:50:53+00:00 1.0001777145903676 0.9998226635928356 1.0
这就是我所做的 -
我制作了一个日期列,以便两个数据框匹配:
ds['date'] = ds.index.date
我重新制作了下午 3 点的数据框,这样就没有多余的日子了:
b = ds.groupby(ds.index.date).apply(lambda x: x.between_time('14:45:00', '14:59:59').tail(1))
b = b.rename(columns={'bid': 'b_bid', 'ask': 'b_ask', 'mid': 'b_mid'})
b.index = b.index.droplevel(1)
b.index = pd.to_datetime(b.index)
b = b.drop(['source'], axis=1)
然后我在一个新的数据框中合并了两个匹配的日期并填写了下午 3 点的报价:
combined = pd.ordered_merge(ds, fix, on='date', fill_method='pad')
combined.index = ds.index
combined = combined.drop(['date'], axis=1)
最后我创建了规范化的列,后来我将它们拉入了它们自己的数据框:
combined['norm_bid'] = combined['bid'] / combined['b_bid']
combined['norm_ask'] = combined['ask'] / combined['b_ask']
combined['norm_mid'] = combined['mid'] / combined['b_mid']
我在数据框 (ds) 中有每天的数据,看起来像这样跨越了几年:
对于每一天,我都需要将所有报价标准化为该特定日期的特定时间。例如,6月1日,我需要将所有报价标准化为6月1日下午3点的报价,但在6月2日,我需要将它们全部标准化为6月2日下午3点的报价。
我有一个包含每天下午 3 点所有报价的数据框,如下所示:
所以我认为如果我可以简单地将我的报价数据帧 (ds) 除以下午 3 点数据帧就可以了:
dr = ds.groupby(ds.index.date).apply(lambda x: x / b)
值得注意的是,下午 3 点的数据框比报价数据框 (ds) 多 天。 因此,报价数据框将必须在 3pm 数据框中划分正确的相应日期,可能使用 b.index.date
我也尝试过不使用单独的数据框,而是从报价数据框 (ds) 本身中提取最后一个可用的报价 - 这也不起作用:
编辑:感谢 DSM 的建议。这有帮助吗?不确定我是否应该 pd.to_string() 数据框,因为它似乎也不容易被剪贴板读取。
引用 ds 数据帧:
bid ask mid
2000-01-04 14:45:12+00:00 281.0 281.5 281.25
2000-01-04 14:46:10+00:00 281.0 282.0 281.5
2000-01-04 14:47:14+00:00 281.2 282.2 281.7
2000-01-04 14:47:22+00:00 281.25 281.85 281.55
2000-01-04 14:47:47+00:00 281.25 281.75 281.5
2000-01-04 14:48:09+00:00 281.4 281.9 281.65
2000-01-04 14:48:40+00:00 281.3 282.3 281.8
2000-01-04 14:49:40+00:00 281.3 281.8 281.55
2000-01-04 14:49:45+00:00 281.2 282.2 281.7
2000-01-04 14:50:53+00:00 281.4 281.9 281.65
3pm 数据帧:
bid_close ask_close price
2000-01-04 15:00:00+00:00 281.35 281.95 281.65
2000-01-05 15:00:00+00:00 280.73 281.48 281.105
2000-01-06 15:00:00+00:00 279.7 280.3 280.0
2000-01-07 15:00:00+00:00 282.3 282.9 282.6
2000-01-10 15:00:00+00:00 281.7 282.3 282.0
2000-01-11 15:00:00+00:00 282.1 282.7 282.4
2000-01-12 15:00:00+00:00 281.9 282.5 282.2
2000-01-13 15:00:00+00:00 281.9 282.7 282.3
2000-01-14 15:00:00+00:00 283.15 283.75 283.45
2000-01-17 15:00:00+00:00 285.5 286.0 285.75
和命令:
c = ds.groupby(ds.index.date).apply(lambda x: x / x.between_time('14:30:00', '14:59:59').resample('30Min', how='last').dropna(how='all'))
我也试过了(看起来很接近):
df = a.groupby(a.index.date).apply(lambda x: x / x.between_time('14:45:00', '14:59:59').tail(1))
这是一个似乎相关的 link(以及我基于上面命令的内容):Grouping daily data by month in python/pandas and then normalizing
这是第一天的简化示例,考虑到 d 是您的 quotes ds dataframe 和 n 是您的 3pm 数据帧:
#get the first day of the 3pm dataframe
first_day = n.index.levels[0][0]
#get the day of the quotes dataframe from the first day of 3pm frame
d1 = d.ix[first_day]
#get the 3pm values for the first day
n1 = n.ix[first_day]
#normalize the bid column, don't forget to modify the range variable
norm = pd.concat([d1[d1.columns[i]].apply(lambda x: x / n1[n1.columns[i]]) for i in range(3)], axis = 1)
>>> norm
15:00:00+00:00 15:00:00+00:00 15:00:00+00:00
14:45:12+00:00 0.9987559978674249 0.9984039723355205 0.9985797976211611
14:46:10+00:00 0.9987559978674249 1.0001773364071644 0.9994674241079354
14:47:14+00:00 0.9994668562288963 1.000886682035822 1.0001775252973548
14:47:22+00:00 0.9996445708192642 0.9996453271856713 0.9996449494052904
14:47:47+00:00 0.9996445708192642 0.9992906543713425 0.9994674241079354
14:48:09+00:00 1.0001777145903676 0.9998226635928356 1.0
14:48:40+00:00 0.9998222854096321 1.0012413548501509 1.0005325758920647
14:49:40+00:00 0.9998222854096321 0.9994679907785069 0.9996449494052904
14:49:45+00:00 0.9994668562288963 1.000886682035822 1.0001775252973548
14:50:53+00:00 1.0001777145903676 0.9998226635928356 1.0
这就是我所做的 -
我制作了一个日期列,以便两个数据框匹配:
ds['date'] = ds.index.date
我重新制作了下午 3 点的数据框,这样就没有多余的日子了:
b = ds.groupby(ds.index.date).apply(lambda x: x.between_time('14:45:00', '14:59:59').tail(1))
b = b.rename(columns={'bid': 'b_bid', 'ask': 'b_ask', 'mid': 'b_mid'})
b.index = b.index.droplevel(1)
b.index = pd.to_datetime(b.index)
b = b.drop(['source'], axis=1)
然后我在一个新的数据框中合并了两个匹配的日期并填写了下午 3 点的报价:
combined = pd.ordered_merge(ds, fix, on='date', fill_method='pad')
combined.index = ds.index
combined = combined.drop(['date'], axis=1)
最后我创建了规范化的列,后来我将它们拉入了它们自己的数据框:
combined['norm_bid'] = combined['bid'] / combined['b_bid']
combined['norm_ask'] = combined['ask'] / combined['b_ask']
combined['norm_mid'] = combined['mid'] / combined['b_mid']