от
У меня есть диктат временных рядов в виде объектов
pandas.DataFrame
, каждый с произвольным числом столбцов. Я хочу преобразовать каждый DataFrame в список dict (например,
[{"col1": "row1", "col2": "row2", ..}, {"col1": "row2", ..}, ..]
, затем отсортировать их по значению timestamp каждого dict (timestamp является обязательным в каждом DataFrame). Это вопрос повышения производительности. Код ниже работает, но я пытаюсь найти самый быстрый способ сделать это. Я знаю, что эту проблему можно распараллелить, но не уверен, что это оптимальный маршрут.
import pandas as pd
import numpy as np


def gen_random_df(rows):
    df = pd.DataFrame({'x': np.random.normal(rows), 'y': np.random.normal(rows), 'z': np.random.normal(rows)},
                      index=pd.date_range('1900

Второй метод:


def method2(dict_of_dfs):
    dict_of_dfs = {symbol: df.assign(symbol=symbol) for symbol, df in dict_of_dfs.items()}
    data = pd.concat(dict_of_dfs.values(), axis=0).reset_index().to_dict('index').values()
    return list(data)

Вот производительность двух подходов. Метод1 самый быстрый, но можно ли его улучшить?
symbols = 10
rows = 10_000
dict_of_dfs = {str(symbol): gen_random_df(rows) for symbol in range(symbols)}

%timeit result = method1(dict_of_dfs)
1.46 s ± 64.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
it
%timeit result = method2(dict_of_dfs)
1.87 s ± 102 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Вот ожидаемый результат:
result[:3]
[{'timestamp': Timestamp('1900
    

        

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.
Анти-спам проверка:
Чтобы избежать проверки в будущем, пожалуйста войдите или зарегистрируйтесь.

1 Ответ

0 голосов
от
Основываясь на этом ответе, я предполагаю, что самым быстрым подходом для
to_list1
было бы не использование
dict
, а скорее глубокое понимание с помощью
chain
для дальнейшей подготовки списка имен (итераций) в качестве расширенного списка имен (для повторной выдачи списков) в качестве повторяющегося списка (в качестве примера).
def to_list1(df, symbol):
    df = df.reset_index()
    cols = list(df.columns)
    cols.append('symbol')

    return [{kk:vv for kk,vv in zip(cols, chain(v, [symbol,]))} for v in df.values]
В моем случае (Python 3.7.2 64b Ubuntu 16.04)
timeit
возвращает:
to_list1: 2.211 s
to_list2: 6.629 s
    
...