#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. Спасибо за ваши предложения. Я не могу поверить, что я об этом не подумал. Я попробую и дам вам знать, если это решит мой вопрос. 🙂