Python 如何在DatetimeIndex的特定时间插入值
我有一个可复制的代码如下:Python 如何在DatetimeIndex的特定时间插入值,python,pandas,datetime,dataframe,Python,Pandas,Datetime,Dataframe,我有一个可复制的代码如下: import pandas as pd import datetime foo = pd.read_csv("http://m.uploadedit.com/bbtc/1545406250692.txt", header=None, names=["Stock","Date","Time", "Open", "High", "Low", "Close", "Volume", "OI"], dtype={"Stock":"category"}, parse_dates
import pandas as pd
import datetime
foo = pd.read_csv("http://m.uploadedit.com/bbtc/1545406250692.txt", header=None, names=["Stock","Date","Time", "Open", "High", "Low", "Close", "Volume", "OI"], dtype={"Stock":"category"}, parse_dates= [['Date', 'Time']], index_col="Date_Time")
foo.sort_index(inplace=True)
bar = foo.between_time('09:00:00', '15:30:00') #Dropping post and pre market data i.e. from index 15:31 - 16:35
#resampling the data by 120 Minutes (2 hours)
twohour = bar.loc["2018-11-22 09:08:00":].resample('120Min',closed = 'right',label = 'left', base=75).agg({'Open': 'first', 'High': 'max', 'Low': 'min','Close': 'last'}).dropna()
twohour.head(7)
Out[]:
Close High Open Low
Date_Time
2018-11-22 07:15:00 321.3 321.30 321.30 321.30
2018-11-22 09:15:00 324.5 326.90 320.10 320.00
2018-11-22 11:15:00 323.2 324.85 324.60 322.20
2018-11-22 13:15:00 319.9 324.35 323.20 319.50
2018-11-22 15:15:00 320.0 320.35 319.85 319.15
2018-11-26 07:15:00 324.90 324.90 324.90 324.90
2018-11-26 09:15:00 311.35 324.40 323.10 309.60
我希望将索引中带时间的Open
列中的每个值09:15:00
替换为索引中带时间的Close
列中的值07:15:00
简而言之,我需要以下输出:
Out[]:
Close High Open Low
Date_Time
2018-11-22 07:15:00 321.3 321.30 321.30 321.30
2018-11-22 09:15:00 324.5 326.90 321.30 320.00
2018-11-22 11:15:00 323.2 324.85 324.60 322.20
2018-11-22 13:15:00 319.9 324.35 323.20 319.50
2018-11-22 15:15:00 320.0 320.35 319.85 319.15
2018-11-26 07:15:00 324.90 324.90 324.90 324.90
2018-11-26 09:15:00 311.35 324.40 324.90 309.60
我尝试使用.loc
将DateTimeindex
转换为字典,然后替换这些值。但是字典没有被排序,所以它需要对dict进行排序,代码变得越来越难看。
非常感谢您的帮助。您可以使用loc选择所需的行,并将打开的列设置为close.shift
import datetime
df.loc[df.index.time == datetime.time(9, 15), 'Open'] = df['Close'].shift(1)
Close High Open Low
Date_Time
2018-11-22 07:15:00 321.30 321.30 321.30 321.30
2018-11-22 09:15:00 324.50 326.90 321.30 320.00
2018-11-22 11:15:00 323.20 324.85 324.60 322.20
2018-11-22 13:15:00 319.90 324.35 323.20 319.50
2018-11-22 15:15:00 320.00 320.35 319.85 319.15
2018-11-26 07:15:00 324.90 324.90 324.90 324.90
2018-11-26 09:15:00 311.35 324.40 324.90 309.60
编辑:比较时间
import time
start = time.clock()
df.loc[df.index.time == datetime.time(9, 15), 'Open'] = df['Close'].shift(1)
print (time.clock() - start)
0.006845999999999464
start = time.clock()
mask_bool = (df.index - df.index.normalize()) == '09:15:00'
df['Open'] = df['Open'].mask(mask_bool, df['Close'].shift(1))
print (time.clock() - start)
0.009392999999999319
在比较之前,您可以将索引转换为
timdelta
或字符串:
# timedelta option, vectorised & efficient
mask_bool = (df.index - df.index.normalize()) == '09:15:00'
# string alternative, inefficient
mask_bool = df.index.strftime('%H:%M') == '09:15'
然后通过loc
或mask
分配:
# Option 1: assign conditionally via loc
df.loc[mask_bool, 'Open'] = df['Close'].shift(1)
# Option 2: mask with pd.Series.mask
df['Open'] = df['Open'].mask(mask_bool, df['Close'].shift(1))
结果:
print(df)
Close High Open Low
Date_Time
2018-11-22 07:15:00 321.30 321.30 321.30 321.30
2018-11-22 09:15:00 324.50 326.90 321.30 320.00
2018-11-22 11:15:00 323.20 324.85 324.60 322.20
2018-11-22 13:15:00 319.90 324.35 323.20 319.50
2018-11-22 15:15:00 320.00 320.35 319.85 319.15
2018-11-26 07:15:00 324.90 324.90 324.90 324.90
2018-11-26 09:15:00 311.35 324.40 324.90 309.60
绩效基准
对于较大的数据帧,timedelta
矢量化版本应该是有效的,但请注意,这将取决于系统和设置:
# Python 3.6.5, Pandas 0.23, NumPy 1.14.3
import pandas as pd
from datetime import time
df = pd.DataFrame.from_dict({'Date_Time': ['2018-11-22 07:15:00', '2018-11-22 09:15:00',
'2018-11-22 11:15:00', '2018-11-22 13:15:00',
'2018-11-22 15:15:00', '2018-11-26 07:15:00',
'2018-11-26 09:15:00'],
'Close': [321.3, 324.5, 323.2, 319.9, 320.0, 324.9, 311.35],
'High': [321.3, 326.9, 324.85, 324.35, 320.35, 324.9, 324.4],
'Open': [321.3, 321.3, 324.6, 323.2, 319.85, 324.9, 324.9],
'Low': [321.3, 320.0, 322.2, 319.5, 319.15, 324.9, 309.6]})
df['Date_Time'] = pd.to_datetime(df['Date_Time'])
df = df.set_index('Date_Time')
df = pd.concat([df]*10**4)
%timeit (df.index - df.index.normalize()) == '09:15:00' # 8.67 ms
%timeit df.index.strftime('%H:%M') == '09:15' # 651 ms
%timeit df.index.time == time(9, 15) # 28.3 ms
在您的数据框中,有两行的'Date\u Time'列值为'07:15:00'。在替换时,您如何决定选择哪一个?在您有9:15的数据但没有7:15的记录的日期会发生什么?@L.B.我想用输出中显示的时间为9:15:00的索引上方的数据替换。@ALOLZ这不会发生,但如果发生,我不想更改任何内容,我会保持数据原样。@L.B.还没有,15分钟后再试。
datetime.time(9,15)
似乎不起作用,是吗?错误:TypeError:描述符“time”需要一个“datetime.datetime”对象,但收到了一个“int”
@zyxue Needimport datetime
非从datetime导入datetime
您需要导入datetime@Vaishali,抱歉,忘记更换所有df
。代码工作得很好。再次感谢@ArJuN,我刚刚添加了时间比较谢谢@jpp。根据您的说法,哪种答案/代码更快?您的答案还是Vaishali的答案?@ArJuN,请参阅更新,为布尔掩码瓶颈计时,timedelta
选项是3个选项中最适合较大数据帧的选项。您能用这两行代码再次计时吗?我还是越来越善于利用时间loc@Vaishali,我也看到了同样的情况,我添加了带有版本号的完整基准测试代码,并添加了免责声明。当然,基准测试依赖于系统。这是因为您只比较创建掩码的代码。当您基于切片分配数据时,会发生大量操作。我用两行代码检查了时间。不管怎样,我只是好奇,所以想看看我是否遗漏了什么。