Более быстрые альтернативы Pandas pivot_table - PullRequest
0 голосов
/ 28 марта 2019

Я использую функцию Pandas pivot_table для большого набора данных (10 миллионов строк, 6 столбцов). Поскольку время выполнения имеет первостепенное значение, я пытаюсь ускорить процесс. В настоящее время обработка всего набора данных занимает около 8 секунд, что значительно замедляет работу, и я надеюсь найти альтернативы для повышения скорости / производительности.

Моя текущая Панда pivot_table:

df_pivot = df_original.pivot_table(index="industry", columns = "months",
                    values = ["orders", "client_name"],
                    aggfunc ={"orders": np.sum, "client_name": pd.Series.nunique})

df_original включает в себя все данные (10-метровые строки, импортированные из CSV). Отрасль - это отрасль клиента, месяцы - это месяцы заказов (с января по декабрь), количество заказов - это количество заказов. Все данные были преобразованы в данные categorical, кроме количества заказов (тип данных int). Первоначально отрасль, месяцы и client_name были строками.

Я пытался использовать pandas.DataFrame.unstack - что было еще медленнее. Также я экспериментировал с Dask. dask pivot_table дал некоторое улучшение (время выполнения 6 секунд - так на 2 секунды меньше). Тем не менее, это все еще довольно медленно. Есть ли более быстрые альтернативы (для больших наборов данных)? Возможно воссоздание сводной таблицы с groupy, crosstab, ... К сожалению, я не получил альтернативы для работы вообще, и я все еще довольно плохо знаком с Python и Pandas ... Ждем ваших предложений. Заранее спасибо!

Обновление:

Я выяснил групповой путь с помощью:

df_new = df_original.groupby(["months", "industry"]).agg({"orders": np.sum, "client_name": pd.Series.nunique}).unstack(level="months").fillna(0)

Теперь это намного быстрее, примерно через 2-3 секунды. Есть ли еще варианты для улучшения скорости?

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Преобразование столбцов месяцев и отрасли в категориальные столбцы: https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html Таким образом вы избежите большого количества сравнений строк.

0 голосов
/ 30 марта 2019

Когда вы читаете файл csv в df, вы можете передать функцию преобразования (через параметр read_csv converters), чтобы преобразовать client_name в хеш и уменьшить orders к соответствующему типу int, в частности, без знака.

Эта функция перечисляет типы и их диапазоны:

import numpy as np

def list_np_types():
    for k, v in np.sctypes.items():
        for i, d in enumerate(v):
            if np.dtype(d).kind in 'iu':
                # only int and uint have a definite range
                fmt = '{:>7}, {:>2}: {:>26}  From: {:>20}\tTo: {}'
                print(fmt.format(k, i, str(d),
                                 str(np.iinfo(d).min),
                                 str(np.iinfo(d).max)))

            else:
                print('{:>7}, {:>2}: {:>26}'.format(k, i, str(d)))


list_np_types()

Выход:

    int,  0:       <class 'numpy.int8'>  From:                 -128 To: 127
    int,  1:      <class 'numpy.int16'>  From:               -32768 To: 32767
    int,  2:      <class 'numpy.int32'>  From:          -2147483648 To: 2147483647
    int,  3:      <class 'numpy.int64'>  From: -9223372036854775808 To: 9223372036854775807
   uint,  0:      <class 'numpy.uint8'>  From:                    0 To: 255
   uint,  1:     <class 'numpy.uint16'>  From:                    0 To: 65535
   uint,  2:     <class 'numpy.uint32'>  From:                    0 To: 4294967295
   uint,  3:     <class 'numpy.uint64'>  From:                    0 To: 18446744073709551615
  float,  0:    <class 'numpy.float16'>
  float,  1:    <class 'numpy.float32'>
  float,  2:    <class 'numpy.float64'>
complex,  0:  <class 'numpy.complex64'>
complex,  1: <class 'numpy.complex128'>
 others,  0:             <class 'bool'>
 others,  1:           <class 'object'>
 others,  2:            <class 'bytes'>
 others,  3:              <class 'str'>
 others,  4:       <class 'numpy.void'>
...