Reputation: 490
I have a 2d numpy array and a list of numbers. If the list is [1, 3, 1, 8]
where the list sums to the number of rows, I want to output an array with the first row unchanged, the next three rows summed, the fifth row unchanged, and the remaining eight rows summed.
As an example:
A = [[0,0], [1,2], [3,4]]
and l = [1, 2]
would output [[0,0], [4,6]
I looked through np.sum and other functions but could not find not this functionality. Thank you.
Upvotes: 1
Views: 925
Reputation: 490
I ended up coming up with my own solution when I realized I could sort my list without affecting my desired output. I used np.unique to determine the first indices of each element in the sorted list and then summed the rows between those indices. See below.
elements, indices = np.unique(data, return_counts=True)
row_summing = np.append([0], np.cumsum(indices))[:-1] #[0, index1, index2,...]
output = np.add.reduceat(matrix, row_summing, axis=0)
Upvotes: 1
Reputation: 11602
If the number of elements in l
is relatively large large, you might get better performance by using groupby
from pandas
, e.g.
import pandas as pd
labels = np.repeat(np.arange(1, len(l) + 1), l)
# [1, 2, 2]
df = pd.DataFrame(A)
df['label'] = labels
result = df.groupby('label').sum().values
Upvotes: 1
Reputation: 11198
You can just iterate over the indices of l
and based on the position either take that row or sum over a range of rows.
import numpy as np
A = [[0,0], [1,2], [3,4]]
l = [1, 2]
ans = []
for i in range(len(l)):
if i%2 == 0:
ans.append(A[ l[i] ])
else:
ans.append( np.sum( A[ l[i-1]:l[i-1] + l[i] ], axis=0 ) )
ans = np.array(ans)
print(ans)
[[1 2]
[4 6]]
N.B:
If the list is [1, 3, 1, 8] where the list sums to the number of rows, I want to output an array with the first row unchanged, the next three rows summed, the fifth row unchanged, and the remaining eight rows summed.
[1, 3, 5, 8]
Upvotes: 1