Я запускаю определенные числовые симуляции в numba.
Выходные данные представляют собой набор массивов numpy; каждый массив представляет собой метрику, и каждый массив имеет форму (периоды x элементы).
Например. metric_1[p,i] сообщает мне значение metric_1 в момент времени p для элемента i.
Каждый элемент принадлежит к определенной категории – скажем, красный и зеленый, просто для примера.
Категории одномерных массивов говорят мне именно об этом - например. категории[0]='a' означает, что первый элемент принадлежит категории a. Концептуально это похоже на «сведение» мультииндекса pandas в другой массив.
Что я пытаюсь сделать
- Я хочу сгруппировать по категориям и создать массив metric_1_grouped с измерениями (периоды x категории) и т. д.
- Я хочу создать по одному фрейму данных для каждой категории, и один с суммой всех категорий, где каждая строка — это точка, а каждый столбец — показатель.
- 300 периодов
- 12 показатели
- 500 000 элементов
- 6 категорий
Мне известно о нескольких вопросах, в которых спрашивают, есть ли эквивалент groupby в numpy, например. Есть ли какая-либо группа по функциям? но они разные, потому что все они группируются по элементу самого массива. Это не то, что я пытаюсь сделать - мне нужно группировать, да, но не по какому-либо элементу самого массива, а скорее путем сопоставления номеров столбцов с другим массивом.Есть вопросы, в которых упоминается суммирование по позициям, но, если я их правильно понял, они не похожи на мой случай, например. Сопоставьте массив numpy и суммируйте значения по позициям в другом массиве и суммируйте массив с условием в другом массиве с помощью numpy
Потенциальные решения
- < li>Кадры данных pandas с мультииндексом — но боюсь, это может быть намного медленнее
- itertools groupby? Признаюсь, я не очень знаком
Код, который у меня есть ниже, работает, но неэлегантный и какой-то неуклюжий. Я надеюсь, что существует лучшая/более элегантная/быстрая версия:
import numpy as np
import pandas as pd
num_periods = 300
num_items = 1000
# Let's suppose for simplicity that the data has already been sorted by category
categories = np.empty(num_items, dtype=object)
categories[0:100]='a'
categories[100:300]='b'
categories[300:600]='c'
categories[600:]='d'
rng = np.random.default_rng(seed=42) #setting a seed for reproducibility
metric_1 = rng.normal(0,1,(num_periods,num_items))
metric_2 = rng.uniform(0,1,(num_periods,num_items))
unique_categories = np.unique(categories)
num_categories=len(unique_categories)
where_to_split = np.unique(categories, return_index=True)[1][1:]
# The second item of the tuple returned by np.unique is an array with the
# indices of the categores (which, remember, we had already sorted - this is
# a requirement),
# so it will be: [0, 100, 300. 600]
# so where_to_split is an array which is [100, 300, 600]
metric_1_list = np.split(metric_1, where_to_split, axis=1)
metric_1_by_category = np.zeros((num_periods, num_categories))
for i in range(len(metric_1_list)):
metric_1_by_category[:,i] = metric_1_list.sum(axis=1)
metric_2_list = np.split(metric_2, where_to_split, axis=1)
metric_2_by_category = np.zeros((num_periods, num_categories))
for i in range(len(metric_2_list)):
metric_2_by_category[:,i] = metric_2_list.sum(axis=1)
# we now create a dictionary of dataframes
# df_by_cat['a'] will be the dataframe for categiry a, etc
df_by_cat = {}
for my_count, my_val in enumerate(unique_categories):
df_by_cat[my_val] = pd.DataFrame(index = np.arange(0,num_periods), columns=['metric 1','metric 2'])
df_by_cat[my_val]['metric 1'] = metric_1_by_category[:,my_count]
df_by_cat[my_val]['metric 2'] = metric_2_by_category[:,my_count]
Подробнее здесь: https://stackoverflow.com/questions/761 ... other-arra
Мобильная версия