Перебор нескольких кадров данных строка за строкой — есть ли способы увеличить скорость?

#python-3.x #pandas #dataframe #loops

#python-3.x #панды #фрейм данных #петли

Вопрос:

У меня есть около 19 фреймов данных с индексами даты и времени, и я хочу перебирать каждый из них параллельно. Поэтому я начинаю с одного df, срезаю его на заданный временной диапазон и делаю то же самое с остальными. Это завершает всю итерацию цикла while. Во время следующей итерации я хочу создать новый срез, начиная с конца старого среза до следующей ближайшей отметки времени всех кадров данных. Я придумал этот код, и он работает, но из-за большого количества итераций он занимает довольно много времени, и мне интересно, есть ли более быстрый способ сделать это.

 import pandas as pd import datetime  # creating test data frames df1 = pd.DataFrame({'A': range(9)}) df1.index = [pd.Timestamp('20130101 09:00:00'),  pd.Timestamp('20130101 09:01:00'),  pd.Timestamp('20130101 09:30:00'),  pd.Timestamp('20130101 09:44:00'),  pd.Timestamp('20130101 09:50:00'),  pd.Timestamp('20130101 10:16:00'),  pd.Timestamp('20130101 10:47:00'),  pd.Timestamp('20130101 10:53:00'),  pd.Timestamp('20130101 11:22:00')]  df2 = pd.DataFrame({'B': range(9)}) df2.index = [pd.Timestamp('20130101 09:00:00'),  pd.Timestamp('20130101 09:01:00'),  pd.Timestamp('20130101 09:04:00'),  pd.Timestamp('20130101 09:05:00'),  pd.Timestamp('20130101 09:09:00'),  pd.Timestamp('20130101 10:10:00'),  pd.Timestamp('20130101 10:15:00'),  pd.Timestamp('20130101 10:16:00'),  pd.Timestamp('20130101 11:18:00')]  db_dict = {"a": df1, "b": df2}   time_dict_start = {} time_dict_end = {} complete_list = [] start_time = datetime.datetime.now()  # starting the main loop while True:  # check if all data has been processed  if len(complete_list) == len(db_dict):  print(datetime.datetime.now() - start_time)  break    # iterate over every data frame  for name in db_dict:    # skip completed data frames  if name in complete_list:  continue   db = db_dict[name]    # first iteration  if name not in time_dict_start:  start = db.index[0]  end = start   datetime.timedelta(seconds=10)  # all other iterations  else:  start = time_dict_start[name]  # get smallest time stamp  time_list = [v for k, v in time_dict_end.items()]  time_list.sort()  end = time_list[0]   time_dict_start[name] = end   datetime.timedelta(seconds=1)   split = db.loc[start: end]   try:  # find next closest index  next_idx = db.index[np.searchsorted(db.index, end   datetime.timedelta(seconds=1))]  time_dict_end[name] = next_idx  except IndexError:  del time_dict_end[name]  complete_list.append(name)   # do something with the sliced data frame  

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

1. Привет, взгляните на модуль и pool функцию многопроцессорной обработки. Для ожидания завершения нескольких параллельных кодов и отправки результатов в другую часть это может быть немного сложно.

Ответ №1:

Поможет ли это объединить фреймы данных? Например, вот один из способов объединения фреймов данных:

 df1.index.name = 'time_stamp' df1.columns.name = 'group'  df2.index.name = 'time_stamp' df2.columns.name = 'group'  print(  pd.concat((df1, df2), axis=1)  .unstack()  .loc[ lambda x: x.notna() ]  .astype(int)  .reset_index()  .sort_values(['time_stamp', 'group'])  .rename(columns = {0: 'value'}) )  

Первые 5 строк являются:

 group time_stamp value 0 A 2013-01-01 09:00:00 0 9 B 2013-01-01 09:00:00 0 1 A 2013-01-01 09:01:00 1 10 B 2013-01-01 09:01:00 1 11 B 2013-01-01 09:04:00 2  

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

1. Спасибо за ваши предложения. Я не могу поверить, что я об этом не подумал. Я попробую и дам вам знать, если это решит мой вопрос. 🙂