Pandas multiindex создание производительности - PullRequest
5 голосов
/ 13 июня 2019

Тесты производительности для создания равных pd.MultiIndex с использованием различных методов класса:

import pandas as pd

size_mult = 8
d1 = [1]*10**size_mult
d2 = [2]*10**size_mult

pd.__version__
'0.24.2'

А именно .from_arrays, from_tuples, from_frame:

# Cell from_arrays
%%time
index_arr = pd.MultiIndex.from_arrays([d1, d2], names=['a', 'b'])
# Cell from_tuples
%%time
index_tup = pd.MultiIndex.from_tuples(zip(d1, d2), names=['a', 'b'])
# Cell from_frame
%%time
df = pd.DataFrame({'a':d1, 'b':d2})
index_frm = pd.MultiIndex.from_frame(df)

Соответствующие выходные данные для ячеек:

# from_arrays
CPU times: user 1min 15s, sys: 6.58 s, total: 1min 21s
Wall time: 1min 21s
# from_tuples
CPU times: user 26.4 s, sys: 4.99 s, total: 31.4 s
Wall time: 31.3 s
# from_frame
CPU times: user 47.9 s, sys: 5.65 s, total: 53.6 s
Wall time: 53.7 s

И давайте проверим, что все результаты одинаковы для случая

index_arr.difference(index_tup)
index_arr.difference(index_frm)

Все строки дают:

MultiIndex(levels=[[1], [2]],
           codes=[[], []],
           names=['a', 'b'])

Так почемуесть ли такая большая разница?from_arrays почти в 3 раза медленнее, чем from_tuples.Это даже медленнее, чем создание DataFrame и создание индекса поверх него.

EDIT:

Я провел еще один более обобщенный тест, и результат оказался на удивление обратным:

np.random.seed(232)

size_mult = 7
d1 = np.random.randint(0, 10**size_mult, 10**size_mult)
d2 = np.random.randint(0, 10**size_mult, 10**size_mult)

start = pd.Timestamp.now()
index_arr = pd.MultiIndex.from_arrays([d1, d2], names=['a', 'b'])
print('ARR done in %f' % (pd.Timestamp.now()-start).total_seconds())

start = pd.Timestamp.now()
index_tup = pd.MultiIndex.from_tuples(zip(d1, d2), names=['a', 'b'])
print('TUP done in %f' % (pd.Timestamp.now()-start).total_seconds())
ARR done in 9.559764
TUP done in 70.457208

Так что теперь from_tuples значительно медленнее, хотя исходные данные те же.

...