Повышение эффективности гармонического среднего в Pandas pivot_table - PullRequest
1 голос
/ 24 мая 2019

Я применяю среднее гармоническое значение из scipy.stats для параметра aggfunc в pivot_table для Pandas, но оно намного медленнее, чем простое среднее на порядки.

Я хотел бы знать, является ли это исключительным поведением или есть способ сделать этот расчет более эффективным, поскольку мне нужно выполнять этот расчет тысячи раз.

Мне нужно использовать среднее гармоническое, но это занимает огромное количество времени на обработку.

Я пытался использовать harmonic_mean из статистической формы Python 3.6, но накладные расходы остались прежними.

Спасибо

import numpy as np
import pandas as pd
import statistics

data = pd.DataFrame({'value1':np.random.randint(1000,size=200000),
                     'value2':np.random.randint(24,size=200000),
                     'value3':np.random.rand(200000)+1,
                     'value4':np.random.randint(100000,size=200000)})

%timeit result = pd.pivot_table(data,index='value1',columns='value2',values='value3',aggfunc=hmean)
1.74 s ± 24.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit result = pd.pivot_table(data,index='value1',columns='value2',values='value3',aggfunc=lambda x: statistics.harmonic_mean(list(x)))
1.9 s ± 26.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit result = pd.pivot_table(data,index='value1',columns='value2',values='value3',aggfunc=np.mean)
37.4 ms ± 938 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

#Single run for both functions
%timeit hmean(data.value3[:100])
155 µs ± 3.17 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit np.mean(data.value3[:100])
138 µs ± 1.07 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

1 Ответ

2 голосов
/ 24 мая 2019

Я бы порекомендовал использовать multiprocessing.Pool , приведенный ниже код был протестирован на 20 миллионов записей, он в 3 раза быстрее оригинального, попробуйте, пожалуйста, для уверенности, что код все еще нуждается в улучшении ответьте на свой конкретный вопрос о медленной производительности statistics.harmonic_mean. примечание: вы можете получить еще лучшие результаты для записей> 100 M.

import time
import numpy as np
import pandas as pd
import statistics
import multiprocessing

data = pd.DataFrame({'value1':np.random.randint(1000,size=20000000),
                     'value2':np.random.randint(24,size=20000000),
                     'value3':np.random.rand(20000000)+1,
                     'value4':np.random.randint(100000,size=20000000)})


def chunk_pivot(data):
    result = pd.pivot_table(data,index='value1',columns='value2',values='value3',aggfunc=lambda x: statistics.harmonic_mean(list(x)))
    return result


DataFrameDict=[]
for i in range(4):
    print(i*250,i*250+250)
    DataFrameDict.append(data[:][data.value1.between(i*250,i*250+249)])

def parallel_pivot(prcsr):
# 6 is a number of processes I've tested
    p = multiprocessing.Pool(prcsr)
    out_df=[]
    for result in p.imap(chunk_pivot, DataFrameDict):
        #print (result)
        out_df.append(result)
    return out_df

start =time.time()
dict_pivot=parallel_pivot(6)
multiprocessing_result=pd.concat(dict_pivot,axis=0)
#singleprocessing_result = pd.pivot_table(data,index='value1',columns='value2',values='value3',aggfunc=lambda x: statistics.harmonic_mean(list(x)))
end = time.time()
print(end-start)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...