Franc Weser
Franc Weser

Reputation: 869

Numpy Aggregate Rows and Sum

I have a Numpy matrix:

M = [[55, 5],
 [56, 3],
 [57, 7],
 [58, 9],
 [59, 3],
 [60, 8],
 [61, 1]] 

I want to aggregate by group_size (for example into 3 groups):

group_size = math.ceil(M.size/groups) # math.ceil(7/3) = 3

Each aggregated row has a left value being the first left value from the group, and the right value being the sum of all right values from the group.

Expected output:

R = [[55, 15], # 55 first left column value of first group, 15 sum of all right values in group 
 [58, 20], # 58 first left column value of second group, 20 sum of all right values in group
 [61, 1]] # Third group consist only of one row, remainder

Is there an efficient way to solve this with Numpy without looping?

Upvotes: 1

Views: 2442

Answers (4)

Mohammad reza Kashi
Mohammad reza Kashi

Reputation: 369

a = np.array([[2, 3],[5, 6],[7, 9]])
b = numpy.zeros(shape=(len(a[0])))
for i in a:
    b=b+i
    print(b)

Upvotes: 0

Dani Mesejo
Dani Mesejo

Reputation: 61910

A solution using Python:

from operator import itemgetter

M = [[55, 5],
     [56, 3],
     [57, 7],
     [58, 9],
     [59, 3],
     [60, 8],
     [61, 1]]
it = (M[e:e+3] for e in range(0, len(M), 3))
print([[e[0][0], sum(map(itemgetter(1), e))] for e in it])

Output

[[55, 15], [58, 20], [61, 1]]

Upvotes: 1

jpp
jpp

Reputation: 164693

Here's one way with NumPy:

n = 3
x = M[::n, 0]
y = np.add.reduceat(M[:, 1], np.arange(0, M.shape[0], n))

R = np.vstack((x, y)).T

print(R)

array([[55, 15],
       [58, 20],
       [61,  1]])

Upvotes: 3

jezrael
jezrael

Reputation: 862761

pandas solution should be use agg with first and sum:

group_size = 3
df = pd.DataFrame(M).groupby(np.arange(len(M)) // group_size).agg({0:'first',1:'sum'})
print (df)
    0   1
0  55  15
1  58  20
2  61   1

a = np.array(df.values.tolist())
print(a)
[[55 15]
 [58 20]
 [61  1]]

Upvotes: 3

Related Questions