Как подсчитать значения между временными метками в фрейме данных pandas

#python #pandas #count #timestamp

#python #pandas #подсчет #временная метка

Вопрос:

У меня есть фрейм данных Pandas, который выглядит следующим образом:

 >>> df
       Start_Time           End_Time
0      2014-10-16 15:05:17  2014-10-16 17:13:14
1      2014-10-16 14:56:37  2014-10-16 15:07:17
2      2014-10-16 14:25:16  2014-10-16 18:06:17
...
  

Теперь у меня есть другой фрейм данных, содержащий несколько временных меток:

 >>> times
       Time           
0      2014-10-16 15:17:17
1      2014-10-16 14:53:37
2      2014-10-16 14:26:16
...
  

В итоге я хочу получить количество строк, где Start_Time < Times < End_Time:

 >>> times
       Time                 Count          
0      2014-10-16 15:17:17  1
1      2014-10-16 15:05:37  2
2      2014-10-16 14:26:16  1
...
  

Конечно, я мог бы сделать это, выполнив итерацию по временам и создав sub_dfs с использованием loc:

   ls_len = []    
  for index, row in times.iterrows():
     sub_df = df.loc[(df['Start_Time']<row['Time']) amp; (df['End_Time']>row['Time'])]
     ls_len.append(len(sub_df))
  times['Count'] = ls_len
  

Но это отнимает много времени и кажется неоптимальным. Есть ли способ выполнить эту операцию без итерации?
Заранее большое вам спасибо, ребята!

Комментарии:

1. Каков размер обоих DataFrame s?

2. К сожалению, довольно огромный, первый содержит несколько миллионов строк.

3. Может быть, вы можете разделить оригинал df на несколько меньших, чтобы ускорить поиск?

4. Я мог бы попробовать, но это было бы основано на множестве предположений (например, продолжительность каждой строки [end_time-start_time] не должна быть больше нескольких дней), так что это было бы немного рискованно.

Ответ №1:

   #This is more optimal than looping        
  def count_val(x):
     sub_df = df.loc[(df['Start_Time']<x['Time']) amp; (df['End_Time']>x['Time'])]
     count = len(sub_df)
     return count

  times['count'] = times.apply(count_val, axis=1)
  

Комментарии:

1. Немного элегантнее: return ((df['Start_Time'] < x['Time']) amp; (x['Time'] < df['End_Time'])).sum()