0

How do I compute the minimum sum of elements in a matrix python? for example:

z = 
np.array([[1, 2, 3], 

 [3, 2, 5], 

 [2, 4, 4]])

The minimum sum of the element is : 1+2+2 = 5

I tried:

def calculate(a):
    sum = 0
    for i in range(len(a)):
        sum += np.sum(a[i])

    return sum

but it gives me 26 instead of 5

Nicolas Gervais
  • 33,817
  • 13
  • 115
  • 143
thenoirlatte
  • 341
  • 3
  • 19

7 Answers7

3

You shouldn't use for loops to perform operations with Numpy arrays. Numpy exists to provide optimized alternatives to loops, and using loops kind of defeats that purpose. You can take the minimum value of each row (collapsing the first axis), then sum up the resulting three values:

np.sum(np.min(z, axis=1))
Out[61]: 5
Nicolas Gervais
  • 33,817
  • 13
  • 115
  • 143
1

You are adding the sum of the entire row to the sum, when you should be adding the minimum value. So just replace sum with min:

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

def calculate(a):
    sum = 0
    for row in a:
        sum += np.min(row)
    return sum

print(calculate(z))

>>> 5

I also optimized your loop method to be clearer.

Mandera
  • 2,647
  • 3
  • 21
  • 26
  • 4
    that does solve your problem but you should take note of the 5 other answers that don't involve a for loop. numpy is literally made for vectorized computations, i.e., not using for loops – Nicolas Gervais Jun 01 '20 at 11:47
  • @NicolasGervais Definitely, your solution is better – Mandera Jun 01 '20 at 11:54
  • @Mandera Don't use `for` loops for solving such a simple problem. And also please don't advocate using `for` loops when you've NumPy arrays. – kmario23 Jun 01 '20 at 17:09
  • @kmario23 Yup, read my comment I made literally right before yours. I just tried to be as intuitive as possible for op. Completely re-doing somebody's code seems very uneducational unless they ask for it – Mandera Jun 01 '20 at 19:41
1

You find np.min over axis 1.

z = np.array([[1, 2, 3], [3, 2, 5], [2, 4, 4]])
z.min(1).sum()
# 5
Ch3steR
  • 20,090
  • 4
  • 28
  • 58
1

You can use np.min():-

z = np.array([[1,2,3],[3,2,5],[2,4,4]])
res = sum(np.min(z, axis=1))
print(res)

Output:

5
Dhaval Taunk
  • 1,662
  • 1
  • 9
  • 17
1

Try:

min_sum = sum(map(np.min,z)) 
print(min_sum) # output: 5
Gabio
  • 9,126
  • 3
  • 12
  • 32
1

You could apply function to find minimum value for each row and sum after that.

import numpy as np
z = np.array([[1, 2, 3], 
             [3, 2, 5], 
             [2, 4, 4]])

np.apply_along_axis(np.min,-1,z).sum()

How this works? First you define the function. Finding the minimum value, in this case. Second you define the axis you wish to find you values. See full description in documentation below. Lasly I run .sum() to sum up all the elements. For studying purposes I suggest running only

np.apply_along_axis(np.min,-1,z)

see more on Numpy documentation

pinegulf
  • 1,334
  • 13
  • 32
0

So, you've z as the following array. In NumPy, you've to understand axis of the array: (please see this answer for a better mental image: very-basic-numpy-array-dimension-visualization ). So, the array here is 2D.

#----> axis: 1      #| a
array([[1, 2, 3],   #| x
       [3, 2, 5],   #| i
       [2, 4, 4]])  #| s
                    #v 0

So, we find minimum along axis 1

In [70]: np.min(z, axis=1) 
Out[70]: array([1, 2, 2])

And since you also need sum, you call .sum() on the resulting 1D array from the above step. Below is the code in a single line:

In [71]: np.min(z, axis=1).sum()   
Out[71]: 5

A general rule of thumb would be to not use for loops with NumPy arrays since that would be awfully slow (in terms of runtime).

kmario23
  • 57,311
  • 13
  • 161
  • 150