Выбор строк с указанными днями в фрейме данных datetimeindex - Pandas
У меня есть датафрейм с datetimeindex. Мне нужны только те строки, индекс которых относится к дням, указанным в списке, например, [1,2] для понедельника и вторника. Может ли это быть возможно в пандах в одной строке кода.
2 ответа
IIUC, тогда должно работать следующее:
df[df.index.to_series().dt.dayofweek.isin([0,1])]
Пример:
In [9]:
df = pd.DataFrame(index=pd.date_range(start=dt.datetime(2015,1,1), end = dt.datetime(2015,2,1)))
df[df.index.to_series().dt.dayofweek.isin([0,1])]
Out[9]:
Empty DataFrame
Columns: []
Index: [2015-01-05 00:00:00, 2015-01-06 00:00:00, 2015-01-12 00:00:00, 2015-01-13 00:00:00, 2015-01-19 00:00:00, 2015-01-20 00:00:00, 2015-01-26 00:00:00, 2015-01-27 00:00:00]
Так что это преобразует DateTimeIndex
к Series
так что мы можем позвонить isin
проверить на членство, используя .dt.dayofweek
и прохождение 0,1
(это соответствует понедельнику и Tuedsay), мы используем логическую маску для маскировки индекса
Другой способ состоит в создании логической маски без преобразования в Series
:
In [12]:
df[(df.index.dayofweek == 0) | (df.index.dayofweek == 1)]
Out[12]:
Empty DataFrame
Columns: []
Index: [2015-01-05 00:00:00, 2015-01-06 00:00:00, 2015-01-12 00:00:00, 2015-01-13 00:00:00, 2015-01-19 00:00:00, 2015-01-20 00:00:00, 2015-01-26 00:00:00, 2015-01-27 00:00:00]
Или на самом деле это будет работать:
In [13]:
df[df.index.dayofweek < 2]
Out[13]:
Empty DataFrame
Columns: []
Index: [2015-01-05 00:00:00, 2015-01-06 00:00:00, 2015-01-12 00:00:00, 2015-01-13 00:00:00, 2015-01-19 00:00:00, 2015-01-20 00:00:00, 2015-01-26 00:00:00, 2015-01-27 00:00:00]
тайминги
In [14]:
%timeit df[df.index.dayofweek < 2]
%timeit df[np.in1d(df.index.dayofweek, [1, 2])]
1000 loops, best of 3: 464 µs per loop
1000 loops, best of 3: 521 µs per loop
Так что мой последний метод здесь немного быстрее, чем метод np
Вы можете попробовать это:
In [3]: import pandas as pd
In [4]: import numpy as np
In [5]: index = pd.date_range('11/23/2015', end = '11/30/2015', freq='d')
In [6]: df = pd.DataFrame(np.random.randn(len(index),2),columns=list('AB'),index=index)
In [7]: df
Out[7]:
A B
2015-11-23 -0.673626 -1.009921
2015-11-24 -1.288852 -0.338795
2015-11-25 -1.414042 -0.767050
2015-11-26 0.018223 -0.726230
2015-11-27 -1.288709 -1.144437
2015-11-28 0.121093 1.396825
2015-11-29 -0.791611 -1.014375
2015-11-30 1.223220 -1.223499
In [8]: df[np.in1d(df.index.dayofweek, [1, 2])]
Out[8]:
A B
2015-11-24 0.116678 -0.715655
2015-11-25 -1.494921 0.218176
1 на самом деле здесь вторник. Но это должно быть довольно легко объяснить, если это необходимо.
Предыдущий ответ был опубликован во время написания этого, для сравнения:
In [15]: %timeit df.loc[df.index.to_series().dt.dayofweek.isin([0,1]).values]
100 loops, best of 3: 2.01 ms per loop
In [16]: %timeit df[np.in1d(df.index.dayofweek, [0, 1])]
1000 loops, best of 3: 393 µs per loop
Обратите внимание, что это сравнение было сделано на тестовом DF, который я создал, и я не знаю, как оно обязательно распространяется на большие кадры данных, хотя производительность должна быть согласованной.