numpy: эффективно получить статистику c по элементам массива, сгруппированным по элементам другого массива - PullRequest
0 голосов
/ 15 января 2020

Заранее извиняюсь за потенциально вводящее в заблуждение название. Я не мог придумать, как правильно сформулировать проблему без наглядного примера.

У меня есть некоторый массив данных (например):

 x = np.array([2,2,2,3,3,3,4,4,4,1,1,2,2,3,3])

и соответствующий массив равной длины, который указывает какие элементы x сгруппированы:

y = np.array([0,0,0,0,0,0,0,0,0,1,1,1,1,1,1])

В этом примере есть две группировки в x: [2,2,2,3,3,3,4,4,4], где y=0; и [1,1,2,2,3,3], где y=1. Я хочу получить статистику c по всем элементам x, где y равно 0, а затем 1. Мне бы хотелось, чтобы это можно было распространить на большие массивы со многими группировками. y всегда упорядочен от низшего к высшему И всегда последовательно увеличивается без пропущенных целых чисел между минимальным и максимальным. Например, y может быть np.array([0,0,**1**,2,2,2,2,3,3,3]) для некоторого массива x такой же длины, но не y = np.array([0,0,**2**,2,2,2,2,3,3,3]), поскольку в нем нет ни одного.

Я могу сделать это довольно грубо, для этого примера.

import numpy as np
x = np.array([2,2,2,3,3,3,4,4,4,1,1,2,2,3,3])
y = np.array([0,0,0,0,0,0,0,0,0,1,1,1,1,1,1])

y_max = np.max(y)
stat_min = np.zeros(y_max+1)
stat_sum = np.zeros(y_max+1)

for i in np.arange(y_max+1):
    stat_min[i] = np.min(x[y==i])
    stat_sum[i] = np.sum(x[y==i])

print(stat_min)
print(stat_sum)

Дает: [2. 1.] и [27. 12.] для статистики минимума и суммы для каждой группировки, соответственно. Мне нужен способ сделать это эффективным для большого числа группировок, где массивы очень велики (> 1 миллион элементов).

EDIT

Чуть лучше с понимание списка.

import numpy as np
x = np.array([2,2,2,3,3,3,4,4,4,1,1,2,2,3,3])
y = np.array([0,0,0,0,0,0,0,0,0,1,1,1,1,1,1])

y_max = np.max(y)

stat_min = np.array([np.min(x[y==i]) for i in range(y_max+1)])
stat_sum = np.array([np.sum(x[y==i]) for i in range(y_max+1)])

print(stat_min)
print(stat_sum)

1 Ответ

1 голос
/ 15 января 2020

Вы помещаете свои массивы в информационный кадр, затем используете groupby и различные его методы: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

import pandas as pd

df = pd.DataFrame({'x': x, 'y': y})` 

mins = df.groupby('y').min()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...