pandas 在特定时间(不是午夜)将数据帧标准化为数据(引号)

Posted

技术标签:

【中文标题】pandas 在特定时间(不是午夜)将数据帧标准化为数据(引号)【英文标题】:pandas Normalize dataframe to data (quotes) at specific time (not midnight) 【发布时间】:2015-06-04 22:56:59 【问题描述】:

我有一个数据框 (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) 本身中提取最后一个可用的报价 - 这也不起作用:

编辑:感谢帝斯曼的建议。这有帮助吗?不确定我是否应该 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

下午 3 点数据帧:

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))

这是一个似乎相关的链接(以及我基于上述命令的内容):Grouping daily data by month in python/pandas and then normalizing

【问题讨论】:

旁白:不仅在问题中插入文本(而不是图像)更容易,而且如果您复制并粘贴文本,其他人可以选择这些部分并使用pd.read_clipboard()重现你的框架。 @DSM 你是否使用 pd.to_clipboard 然后将其粘贴到 SO 中? @camdenl 我已经更新了。我认为它现在大部分是可读的(除了时间戳在日期和时间之间分开)。 【参考方案1】:

这是第一天的简化示例,考虑到 d 是您的 quotes ds dataframen 是您的下午 3 点数据框

#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

【讨论】:

我最终采用了另一种方式(在匹配的“日期”列与原始引号框架的有序合并期间填写下午 3 点的引号,然后将列分开)并得到相同的答案。所以你的答案也有效。谢谢! 可能也值得发布您的解决方案!【参考方案2】:

这就是我所做的 -

我创建了一个日期列,以便两个数据框匹配:

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']

【讨论】:

以上是关于pandas 在特定时间(不是午夜)将数据帧标准化为数据(引号)的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地迭代 Pandas 数据帧的连续块

在特定时间间隔内填充时间序列 pandas 数据帧中的空白

Pandas 基于连接将列从一个数据帧添加到另一个数据帧

查找特定行数 pandas 数据帧的平均值

向量化 Pandas 数据帧

使用 StandardScaler() 规范化 pandas 数据帧,不包括特定列