Boolean mask from pandas datetime index using .loc accessor
假设以下玩具代码:
1 2 3 4 5 6 | import numpy as np import pandas as pd rng = pd.date_range('1/1/2011', periods=72, freq='H') avec = np.random.rand(len(rng)) bvec = np.random.rand(len(rng)) df = pd.DataFrame({"A":avec,"B":bvec}, index=rng) |
我现在可以用
选择时间间隔的一部分
1 | df.loc["2011-01-02",:] |
有没有办法有效地访问对应于结果切片的布尔掩码,即:
1 2 3 4 5 6 7 8 | array([False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], dtype=bool) |
我已经尝试过早期 stackoverflow 答案中的建议,但
如果性能很重要,链 2 布尔掩码:
1 | (df.index >="2011-01-02") & (df.index <"2011-01-03") |
您可以提取索引的
1 2 3 4 5 | import numpy as np from datetime import datetime (df.index.values >= np.datetime64(datetime.strptime("2011-01-02", '%Y-%m-%d'))) & \\ (df.index.values < np.datetime64(datetime.strptime("2011-01-03", '%Y-%m-%d'))) |
行为注意事项
上述解决方案特定于问题中的查询。正如@Jeff 指出的那样,
有关详细信息,请参阅关于
性能基准测试
1 2 3 4 5 6 7 8 9 10 11 12 13 | df = pd.concat([df]*1000) %timeit (df.index >="2011-01-02") & (df.index <"2011-01-03") %timeit (df.index.values >= np.datetime64(datetime.strptime("2011-01-02", '%Y-%m-%d'))) & \\ (df.index.values < np.datetime64(datetime.strptime("2011-01-03", '%Y-%m-%d'))) assert ((df.index >="2011-01-02") & (df.index <"2011-01-03") == \\ (df.index.values >= np.datetime64(datetime.strptime("2011-01-02", '%Y-%m-%d'))) & \\ (df.index.values < np.datetime64(datetime.strptime("2011-01-03", '%Y-%m-%d')))).all() # 1.21 ms ± 23 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # 527 μs ± 11.3 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each) |
IIUC,你可以这样做:
1 2 3 4 5 6 7 8 9 10 | df.index.isin(df.loc["2011-01-02",:].index) array([False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], dtype=bool) |
但是,@jezrael 的回答更快。我将此作为替代解决方案。这提供的唯一便利是如果您想按名称而不是日期字符串引用切片数据帧,例如:
1 2 3 4 | # named slice of your original dataframe: sliced_df = df.loc["2011-01-02",:] # get boolean array: df.index.isin(sliced_df.index) |