Наберите следующий код игрушки:
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)
Теперь я могу выбрать часть временного интервала с помощью
df.loc["2011-01-02",:]
Есть ли способ эффективно получить доступ к булевой маске, соответствующей результирующему срезу, то есть:
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, но df.index.date очень долго запускается в моем наборе данных ...






IIUC, вы можете сделать это:
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 быстрее. Я оставляю это как альтернативное решение. Единственное удобство, которое это обеспечивает, - это если вы хотите ссылаться на свой срезанный фрейм данных по имени, а не по строке даты, например:
# named slice of your original dataframe:
sliced_df = df.loc["2011-01-02",:]
# get boolean array:
df.index.isin(sliced_df.index)
Если производительность важна, цепочка 2 булевых масок:
(df.index >= "2011-01-02") & (df.index < "2011-01-03")
@roganjosh - думаю сравнить решение с isin, но я должен протестировать его на 100% :)
Это действительно быстрее, я только что рассчитал время.
Ах, я предпочитаю ваше решение как оно есть! :)
Вы можете извлечь представление индекса numpy и сравнить его с объектом np.datetime64:
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, строковые представления datetime используют частичную индексацию. Поэтому использование numpy следует использовать только в определенных случаях.
Подробнее см. pandasдокументация по индексации datetime.
Тестирование производительности
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)
в целом это не одно и то же; строка datetime использует частичную индексацию. предлагать numpy soln часто является особым случаем и не рекомендуется
документы: pandas.pydata.org/pandas-docs/stable/timeseries.html#indexin g
Спасибо за решение! Это определенно быстрее, чем у Jezreal, но разница немного уменьшается на больших наборах данных, и я немного беспокоюсь о потреблении памяти. Хотелось бы, чтобы был способ получить эквивалент df.index == "2011-01-02" с частичной индексацией ...
Мне любопытно, почему вы говорите «если производительность важна»? Считаете ли вы, что синтаксис неясен и мог бы быть лучше, если бы производительность не была важна?