Pandas Dataframe: to_dict () низкая производительность - PullRequest
0 голосов
/ 26 января 2019

Я работаю с apis, которые возвращают большие кадры данных панд. Мне не известен быстрый способ итерации по всему фрейму данных, поэтому я приведу к словарю с to_dict().

После того, как мои данные представлены в виде словаря, производительность в порядке. Однако операция to_dict() обычно является узким местом для производительности.

Я часто группирую столбцы информационного кадра вместе, чтобы сформировать мультииндекс, и использую ориентацию «индекс» для to_dict(). Не уверен, что большие многоиндексные диски имеют низкую производительность.

Есть ли более быстрый способ разыграть кадр данных панд? Может быть, есть лучший способ итерации непосредственно по фрейму данных без приведения? Не уверен, есть ли способ, которым я мог бы применить векторизацию.

Ниже приведен пример кода, который имитирует проблему с таймингами:

import pandas as pd
import random as rd
import time

#Given a dataframe from api (model as random numbers)
df_columns = ['A','B','C','D','F','G','H','I']
dict_origin = {col:[rd.randint(0,10) for x in range(0,1000)] for col in df_columns}
dict_origin = pd.DataFrame(dict_origin)

#Transform to pivot table
t0 = time.time()
df_pivot = pd.pivot_table(dict_origin,values=df_columns[-3:],index=df_columns[:-3])
t1 = time.time()
print('Pivot Construction takes: ' + str(t1-t0))

#Iterate over all elements in pivot table
t0 = time.time()
for column in df_pivot.columns:
    for row in df_pivot[column].index:
        test = df_pivot[column].loc[row]
t1 = time.time()
print('Dataframe iteration takes: ' + str(t1-t0))


#Iteration over dataframe too slow. Cast to dictionary (bottleneck)
t0 = time.time()
df_pivot = df_pivot.to_dict('index')
t1 = time.time()
print('Cast to dictionary takes: ' + str(t1-t0))

#Iteration over dictionary is much faster
t0 = time.time()
for row in df_pivot.keys():
    for column in df_pivot[row]:
        test = df_pivot[row][column]
t1 = time.time()
print('Iteration over dictionary takes: ' + str(t1-t0))

Спасибо!

1 Ответ

0 голосов
/ 27 января 2019

Общее руководство: не повторять, использовать функции для всех столбцов строк или для группированных строк / столбцов.Ниже в третьем блоке кода показано, как выполнять итерацию по массиву numpy, который является атрибутом .values.Результаты:

Сводная конструкция занимает: 0,012315988540649414

Итерация кадра данных: 0,32346272468566895

Итерация по значениям занимает: 0,004369020462036133

Приведение к словарю занимает: 0,023524761199951172

Итерация по словарю занимает: 0,0010480880737304688

import pandas as pd
from io import StringIO 

# Test data
import pandas as pd
import random as rd
import time

#Given a dataframe from api (model as random numbers)
df_columns = ['A','B','C','D','F','G','H','I']
dict_origin = {col:[rd.randint(0,10) for x in range(0,1000)] for col in df_columns}
dict_origin = pd.DataFrame(dict_origin)

#Transform to pivot table
t0 = time.time()
df_pivot = pd.pivot_table(dict_origin,values=df_columns[-3:],index=df_columns[:-3])
t1 = time.time()
print('Pivot Construction takes: ' + str(t1-t0))

#Iterate over all elements in pivot table
t0 = time.time()
for column in df_pivot.columns:
    for row in df_pivot[column].index:
        test = df_pivot[column].loc[row]
t1 = time.time()
print('Dataframe iteration takes: ' + str(t1-t0))

#Iterate over all values in pivot table
t0 = time.time()
v = df_pivot.values
for row in range(df_pivot.shape[0]):
    for column in range(df_pivot.shape[1]):
        test = v[row, column]
t1 = time.time()
print('Iteration over values takes: ' + str(t1-t0))


#Iteration over dataframe too slow. Cast to dictionary (bottleneck)
t0 = time.time()
df_pivot = df_pivot.to_dict('index')
t1 = time.time()
print('Cast to dictionary takes: ' + str(t1-t0))

#Iteration over dictionary is much faster
t0 = time.time()
for row in df_pivot.keys():
    for column in df_pivot[row]:
        test = df_pivot[row][column]
t1 = time.time()
print('Iteration over dictionary takes: ' + str(t1-t0))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...