Как я могу использовать или манипулировать (monkey-patch) пандами для того, чтобы всегда сохранять один и тот же мажорный порядок в результирующем объекте для копий и групповых агрегаций?
Я используюpandas.DataFrame
как структура данных в бизнес-приложении (модель риска) и требует быстрой агрегации многомерных данных.Агрегация с пандами в решающей степени зависит от схемы упорядочения мажоров, используемой в базовом массиве numpy.
К сожалению, pandas (версия 0.23.4) меняет мажорный порядок нижележащего массива numpy, когда я создаю копию иликогда я выполняю агрегацию с группированием и суммой.
Воздействие:
, случай 1: 17,2 секунды
, случай 2: 5мин 46 с секунд
в кадре данных и его копии с 45023 строками и 100000 столбцами.Агрегация была выполнена по индексу.Индекс pd.MultiIndex
с 15 уровнями.Агрегация держит три уровня и приводит к 239 группам.
Обычно я работаю с DataFrames с 45000 строк и 100000 столбцов.На ряду у меня есть pandas.MultiIndex
с примерно 15 уровнями.Для вычисления статистики по различным узлам иерархии мне нужно агрегировать (суммировать) по измерению индекса.
Агрегация выполняется быстро, если базовый массив numpy равен c_contiguous
, следовательно, содержится в мажорном столбце (порядок C).Это очень медленно, если оно f_contiguous
, следовательно, в мажорном порядке строк (порядок F).
К сожалению, pandas меняет мажорный порядок с C на F, когда
создает копию DataFrame и даже когда
выполняет агрегацию через группировщика и получает сумму на группере.Следовательно, результирующий DataFrame имеет другой мажорный порядок (!)
Конечно, я мог бы придерживаться другой «модели данных», просто сохраняя MultiIndex на столбцах.Тогда текущая версия для панд всегда будет работать в мою пользу.Но это не пойдет.Я думаю, что можно ожидать, что для двух рассматриваемых операций (сгруппированная сумма и копия) мажорный порядок не должен изменяться.
import numpy as np
import pandas as pd
print("pandas version: ", pd.__version__)
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
array.flags
print("Numpy array is C-contiguous: ", data.flags.c_contiguous)
dataframe = pd.DataFrame(array, index = pd.MultiIndex.from_tuples([('A', 'U'), ('A', 'V'), ('B', 'W')], names=['dim_one', 'dim_two']))
print("DataFrame is C-contiguous: ", dataframe.values.flags.c_contiguous)
dataframe_copy = dataframe.copy()
print("Copy of DataFrame is C-contiguous: ", dataframe_copy.values.flags.c_contiguous)
aggregated_dataframe = dataframe.groupby('dim_one').sum()
print("Aggregated DataFrame is C-contiguous: ", aggregated_dataframe.values.flags.c_contiguous)
## Output in Jupyter Notebook
# pandas version: 0.23.4
# Numpy array is C-contiguous: True
# DataFrame is C-contiguous: True
# Copy of DataFrame is C-contiguous: False
# Aggregated DataFrame is C-contiguous: False
Основной порядок данных должен быть сохранен.Если pandas любит переключаться на неявные предпочтения, то это должно позволить перезаписать это.Numpy позволяет вводить порядок при создании копии.
Исправленная версия панд должна привести к
## Output in Jupyter Notebook
# pandas version: 0.23.4
# Numpy array is C-contiguous: True
# DataFrame is C-contiguous: True
# Copy of DataFrame is C-contiguous: True
# Aggregated DataFrame is C-contiguous: True
для примера кода, приведенного выше.