Логическая маска из индекса datetime pandas с использованием метода доступа .loc

Наберите следующий код игрушки:

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 очень долго запускается в моем наборе данных ...

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
4 018
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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 08.04.2018 17:46

@roganjosh - думаю сравнить решение с isin, но я должен протестировать его на 100% :)

jezrael 08.04.2018 17:46

Это действительно быстрее, я только что рассчитал время.

sacuL 08.04.2018 17:47

Ах, я предпочитаю ваше решение как оно есть! :)

roganjosh 08.04.2018 17:47

Вы можете извлечь представление индекса 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 часто является особым случаем и не рекомендуется

Jeff 08.04.2018 18:06

документы: pandas.pydata.org/pandas-docs/stable/timeseries.html#indexin‌ g

Jeff 08.04.2018 18:08

Спасибо за решение! Это определенно быстрее, чем у Jezreal, но разница немного уменьшается на больших наборах данных, и я немного беспокоюсь о потреблении памяти. Хотелось бы, чтобы был способ получить эквивалент df.index == "2011-01-02" с частичной индексацией ...

brorfred 08.04.2018 18:45

Другие вопросы по теме