У меня есть матрица, которая выглядит так:

M = [[1, 200],
 [1.8, 100],
 [2, 500],
 [2.5, 300],
 [3, 400],
 [3.5, 200],
 [5, 200],
 [8, 100]]

Я хочу сгруппировать строки по размеру бина (применяется к левому столбцу), например, для ячейки размером 2 (первая ячейка имеет значения от 0 до 2, вторая ячейка от 2 до 4, третья ячейка от 4 до 6 и т. д.):

[[1, 200],
 [1.8, 100],
----
 [2, 500],
 [2.5, 300],
 [3, 400],
 [3.5, 200],
----
 [5, 200],
----
 [8, 100]]

Затем выведите новую матрицу с суммой правых столбцов для каждой группы:

[200+100, 500+300+400+200, 200, 100]

Как эффективный способ суммировать каждое значение на основе границ bin_size?

3
Franc Weser 23 Окт 2018 в 18:53

2 ответа

Лучший ответ

С pandas:

Сделайте DataFrame, а затем используйте целочисленное деление для определения ваших бункеров:

import pandas as pd

df = pd.DataFrame(M)
df.groupby(df[0]//2)[1].sum()

#0
#0.0     300
#1.0    1400
#2.0     200
#4.0     100
#Name: 1, dtype: int64

Используйте .tolist(), чтобы получить желаемый результат:

df.groupby(df[0]//2)[1].sum().tolist()
#[300, 1400, 200, 100]

С numpy.bincount

import numpy as np

gp, vals = np.transpose(M)
gp = (gp//2).astype(int)

np.bincount(gp, vals)
#array([ 300., 1400.,  200.,    0.,  100.])
5
ALollz 23 Окт 2018 в 16:16

Вы можете использовать np.digitize и scipy.sparse.csr_matrix здесь:

bins = [2, 4, 6, 8, 10]
b = np.digitize(M[:, 0], bins)
v = M[:, 1]

Теперь используя векторизацию groupby, используя csr_matrix

from scipy import sparse

sparse.csr_matrix(
    (v, b, np.arange(v.shape[0]+1)), (v.shape[0], b.max()+1)
).sum(0)
matrix([[ 300., 1400.,  200.,    0.,  100.]])
2
user3483203 23 Окт 2018 в 16:22
52953231