Выбор строк фрейма данных между двумя датами
Я создаю фрейм данных из csv следующим образом:
stock = pd.read_csv('data_in/' + filename + '.csv', skipinitialspace=True)
фрейм данных имеет столбец даты. Есть ли способ создать новый фрейм данных (или просто перезаписать существующий), который содержит только строки со значениями дат, которые попадают в указанный диапазон дат или между двумя указанными значениями дат?
6 ответов:
есть два возможных решения:
- используйте логическую маску, затем используйте
df.loc[mask]
- установите столбец даты в качестве DatetimeIndex, затем используйте
df[start_date : end_date]
используя логическую маску:
обеспечить
df['date']
- это серия с dtypedatetime64[ns]
:df['date'] = pd.to_datetime(df['date'])
сделать логическую маску.
start_date
иend_date
может бытьdatetime.datetime
s,np.datetime64
s,pd.Timestamp
s, или даже datetime строки:mask = (df['date'] > start_date) & (df['date'] <= end_date)
выберите суб-фрейм данных:
df.loc[mask]
или повторно назначить
df
df = df.loc[mask]
например,
import numpy as np import pandas as pd df = pd.DataFrame(np.random.random((200,3))) df['date'] = pd.date_range('2000-1-1', periods=200, freq='D') mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10') print(df.loc[mask])
доходность
0 1 2 date 153 0.208875 0.727656 0.037787 2000-06-02 154 0.750800 0.776498 0.237716 2000-06-03 155 0.812008 0.127338 0.397240 2000-06-04 156 0.639937 0.207359 0.533527 2000-06-05 157 0.416998 0.845658 0.872826 2000-06-06 158 0.440069 0.338690 0.847545 2000-06-07 159 0.202354 0.624833 0.740254 2000-06-08 160 0.465746 0.080888 0.155452 2000-06-09 161 0.858232 0.190321 0.432574 2000-06-10
используя DatetimeIndex:
если вы собираетесь сделать много выборов по дате, это может быть быстрее, чтобы установить
Я чувствую, что лучшим вариантом будет использовать прямые проверки, а не использовать функцию loc:
df = df[(df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')]
это работает для меня.
основная проблема с функцией loc со срезом заключается в том, что ограничения должны присутствовать в фактических значениях, если это не приведет к KeyError.
можно использовать
isin
метод вот такdf[df["date"].isin(pd.date_range(start_date, end_date))]
Примечание: это работает только с датами (как вопрос), а не метки.
пример:
import numpy as np import pandas as pd # Make a DataFrame with dates and random numbers df = pd.DataFrame(np.random.random((30, 3))) df['date'] = pd.date_range('2017-1-1', periods=30, freq='D') # Select the rows between two dates in_range_df = df[df["date"].isin(pd.date_range("2017-01-15", "2017-01-20"))] print(in_range_df) # print result
что дает
0 1 2 date 14 0.960974 0.144271 0.839593 2017-01-15 15 0.814376 0.723757 0.047840 2017-01-16 16 0.911854 0.123130 0.120995 2017-01-17 17 0.505804 0.416935 0.928514 2017-01-18 18 0.204869 0.708258 0.170792 2017-01-19 19 0.014389 0.214510 0.045201 2017-01-20
в случае, если вы собираетесь делать это часто, лучшим решением было бы сначала установить столбец даты как индекс, который преобразует столбец в DateTimeIndex и использует следующее условие для нарезки любого диапазона дат.
import pandas as pd data_frame = data_frame.set_index('date') df = data_frame[(data_frame.index > '2017-08-10') & (data_frame.index <= '2017-08-15')]
Я предпочитаю не изменять
df
.опция для получения
index
наstart
иend
сроки:import numpy as np import pandas as pd #Dummy DataFrame df = pd.DataFrame(np.random.random((30, 3))) df['date'] = pd.date_range('2017-1-1', periods=30, freq='D') #Get the index of the start and end dates respectively start = df[df['date']=='2017-01-07'].index[0] end = df[df['date']=='2017-01-14'].index[0] #Show the sliced df (from 2017-01-07 to 2017-01-14) df.loc[start:end]
что приводит к:
0 1 2 date 6 0.5 0.8 0.8 2017-01-07 7 0.0 0.7 0.3 2017-01-08 8 0.8 0.9 0.0 2017-01-09 9 0.0 0.2 1.0 2017-01-10 10 0.6 0.1 0.9 2017-01-11 11 0.5 0.3 0.9 2017-01-12 12 0.5 0.4 0.3 2017-01-13 13 0.4 0.9 0.9 2017-01-14