#python #pandas
#python #pandas
Вопрос:
У меня есть два фрейма данных, один с миллионами строк данных, а другой с несколькими сотнями записей, и мне нужно отфильтровать первый фрейм данных по трем столбцам из второго.
Итак, в основном мне нужно выполнить итерацию по каждой строке в df2 и посмотреть, есть ли какие-либо строки в df1 с одинаковыми тикерами и датами между начальной и конечной датой. К сожалению, я понятия не имею, как выполнить это с помощью python.
Итак, мои фреймы данных похожи на следующие
Ticker date
1 AA 2013-12-31
3 AA 2015-02-28
4 AA 2016-03-31
5 AA 2016-04-30
6 BB 2014-05-31
7 BB 2014-06-30
8 BB 2017-07-31
9 CC 2014-08-31
10 CC 2017-09-30
11 CC 2018-10-31
12 CC 2018-11-30
13 DD 2018-11-30
14 DD 2018-12-21
Второй:
Ticker StartDate EndDate
1 AA 2016-01-01 2017-01-01
2 BB 2014-01-01 2015-01-01
3 CC 2018-01-01 2019-01-01
4 AA 2013-01-01 2014-01-01
Мой ожидаемый результат — отфильтрованный первый фрейм данных со всеми записями для всех тикеров в df2 между датами начала и окончания:
Ticker date
1 AA 2013-12-31
2 AA 2016-03-31
3 AA 2016-04-30
4 BB 2014-05-31
5 BB 2014-06-30
6 CC 2018-11-30
UPD
Итак, я попробовал следующее:
df4 = pd.DataFrame()
###create empty dataframe
for index, row in df2.iterrows():
df3 =df1.loc[(df1['DATE']>=row['StartDate'])amp;(df1['DATE']<=row['EndDate'])amp;(df1['Ticker'] ==row['Ticker'])]
###Go through rows of dataframe2, for every row i look if there any rows in df1 that falls under criteria
df4 = df4.append(df3)
### append filtered results of one row to empty dataframe
Это работает, но на это уходит много времени — я пытался отфильтровать 2% своих данных, и это заняло около 25 минут
Есть ли какой-нибудь способ ускорить это?
Ответ №1:
Попробуйте это:
df3 = df1.merge(df2)
df3 =df3.loc[(df3['date']>=df3['StartDate'])amp;(df3['date']<=df3['EndDate'])]
df3.drop(['date'], axis = 1)
Комментарии:
1. Я пробовал аналогичный подход, и он не сработал. Насколько я понимаю, слияние работает аналогично объединению баз данных, и это мне здесь не помогло бы. Второй фрейм данных содержит разные строки с одинаковыми ресурсами, поэтому я не могу присоединиться к ресурсам, а позже просто фильтровать строки, где дата не находится в границах даты окончания / начала
Ответ №2:
Похоже, вы можете использовать group by из create диапазоны дат для каждого тикера
data = pd.read_clipboard()
flt_df = pd.read_clipboard()
данные
Ticker date
1 AA 2013-12-31
3 AA 2015-02-28
4 AA 2016-03-31
5 AA 2016-04-30
6 BB 2014-05-31
7 BB 2014-06-30
8 BB 2017-07-31
9 CC 2014-08-31
10 CC 2017-09-30
11 CC 2018-10-31
12 CC 2018-11-30
13 DD 2018-11-30
14 DD 2018-12-21
fl_df
Ticker StartDate EndDate
1 AA 2016-01-01 2017-01-01
2 BB 2014-01-01 2015-01-01
3 CC 2018-01-01 2019-01-01
4 AA 2013-01-01 2014-01-01
grouped_df = flt_df.groupby('Ticker').agg({'StartDate':'min','EndDate':'max'})
merged = data.set_index('Ticker').join(grouped_df)
merged = merged[(merged.date>=merged.StartDate)amp;(merged.date<=merged.EndDate)]
merged.drop(['StartDate','EndDate'],axis=1,inplace=True)
объединенный
date
Ticker
AA 2013-12-31
AA 2015-02-28
AA 2016-03-31
AA 2016-04-30
BB 2014-05-31
BB 2014-06-30
CC 2018-10-31
CC 2018-11-30