大熊猫一遍又一遍,我发现我必须在特定的时间内分开。例如,对于时间序列中的每一天,将每个值除以中午12:00的值。
我觉得这应该是一个相当简单的操作,但我找不到简单的解决方案。
例如,我想在时间序列中每天执行一项功能:
x = df.groupby(df.index.date).apply(func)
对于每一天,请执行:
def func(df):
st = df.between_time('10:00','10:00')['y-value']
end = df.between_time('14:45','14:45')['y-value']
return (st / end)
首先,有什么方法可以说,df.at_time(' 10:00')?在这里编写.between_time()似乎很迂回但是它有效。我也试过df.index.time,但我不确定怎么说,== datetime.time(10,0),因为它返回一个布尔数组,而不仅仅是上午10:00的值。 / p>
该功能不起作用,因为我认为是一个索引问题,它会在每个值上吐出N / A并为每天吐出两个值(即一个在10:00和14: 45),而不是一个。 如果它们是相同的时间,则可以正常工作,但如果时间不同,则无效。我认为算术运算不能在不同的日期时间干净地工作。
我也尝试过:
def func(df):
st = df.reset_index().between_time('10:00','10:00')['mid'].values[0]
end = df.reset_index().between_time('14:45','14:45')['mid'].values[0]
return (st / end)
我收到索引错误,说我需要返回DateTimeIndex。我认为我不能将值除以,它会将该值返回到相应的日期,而是需要返回某种(索引,值)pandas对象。
有什么想法吗?这是一项常见的操作吗?
这是我的数据集的样子(使用pd.read_clipboard()来读取):
bid ask mid
2000-01-01 12:00:00 288.0 289.5 288.75
2000-01-01 13:30:00 287.8 288.6 288.20000000000005
2000-01-01 14:00:00 287.75 289.25 288.5
2000-01-03 09:30:00 288.5 289.5 289.0
2000-01-03 10:15:00 288.5 289.5 289.0
2000-01-03 10:30:00 289.0 290.0 289.5
2000-01-03 10:45:00 288.75 289.75 289.25
2000-01-03 11:45:00 288.75 289.75 289.25
2000-01-03 13:00:00 288.5 289.5 289.0
2000-01-03 13:15:00 288.5 289.5 289.0
2000-01-03 13:30:00 288.5 289.5 289.0
2000-01-04 09:00:00 281.5 282.25 281.875
2000-01-04 09:15:00 281.0 281.5 281.25
2000-01-04 09:30:00 281.25 281.75 281.5
2000-01-04 09:45:00 281.1 281.85 281.475
2000-01-04 10:00:00 281.7 282.2 281.95
2000-01-04 10:30:00 282.0 282.75 282.375
2000-01-04 10:45:00 282.2 282.95 282.575
2000-01-04 11:15:00 282.3 282.8 282.55
2000-01-04 11:30:00 281.45 282.2 281.825
更新:暂时修复,但我正在寻找更清洁的东西(它可能不存在)
st_time, end_time = '8:00', '14:45'
st, end = df.at_time(st_time), df.at_time(end_time)
AM = st.merge(end, on='date', how='left').dropna()
AM = AM.set_index(pd.DatetimeIndex(AM['date']))
AM['AM return'] = (AM[end_time] / AM[st_time]) - 1
AM = AM.rename(columns={'price_x': st_time+' price', 'price_y': end_time+' price'})
答案 0 :(得分:0)
这是一种做我想要的想法的方法。
将原始帧重新索引为包含范围内的所有日期。这确保'12:00'存在;向前填充以传播价值观。
In [66]: y = df.reindex(pd.date_range(df.index.min().date(),(df.index.max() + pd.offsets.Day()).date(), closed='left', freq='15T'), method='ffill')
In [67]: y.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 384 entries, 2000-01-01 00:00:00 to 2000-01-04 23:45:00
Freq: 15T
Data columns (total 3 columns):
bid 336 non-null float64
ask 336 non-null float64
mid 336 non-null float64
dtypes: float64(3)
memory usage: 12.0 KB
将新系列除以'12:00'值。请注意,您必须在此处删除索引(使用.values)以正确地广播它。重新索引回原始框架。
In [68]: (y/y.groupby(y.index.date).transform(lambda x: x.at_time('12:00').values)).reindex(df.index)
Out[68]:
bid ask mid
2000-01-01 12:00:00 1.000000 1.000000 1.000000
2000-01-01 13:30:00 0.999306 0.996891 0.998095
2000-01-01 14:00:00 0.999132 0.999136 0.999134
2000-01-03 09:30:00 0.999134 0.999137 0.999136
2000-01-03 10:15:00 0.999134 0.999137 0.999136
2000-01-03 10:30:00 1.000866 1.000863 1.000864
2000-01-03 10:45:00 1.000000 1.000000 1.000000
2000-01-03 11:45:00 1.000000 1.000000 1.000000
2000-01-03 13:00:00 0.999134 0.999137 0.999136
2000-01-03 13:15:00 0.999134 0.999137 0.999136
2000-01-03 13:30:00 0.999134 0.999137 0.999136
2000-01-04 09:00:00 1.000178 1.000177 1.000177
2000-01-04 09:15:00 0.998401 0.997519 0.997960
2000-01-04 09:30:00 0.999289 0.998405 0.998847
2000-01-04 09:45:00 0.998756 0.998760 0.998758
2000-01-04 10:00:00 1.000888 1.000000 1.000444
2000-01-04 10:30:00 1.001954 1.001949 1.001952
2000-01-04 10:45:00 1.002665 1.002658 1.002661
2000-01-04 11:15:00 1.003020 1.002126 1.002573
2000-01-04 11:30:00 1.000000 1.000000 1.000000
这应该对您的输入范围和矢量化都很稳健。但是我认为可以改进语法/易用性。