juankirr
juankirr

Reputation: 323

A more elegant and simple way to traverse the elements of an array in python?

(kk is a 3D array) This is a classic way to "travel around" a 3D array. I am new in python and I sense that there must be a much more elegant way in python

for i in range(len(kk)):
  for j in range(len(kk[i])):
      if np.average(kk[i][j]) >0.70:
        kk[i][j]=1.0
      else:
        if np.average(kk[i][j])>0.50:
          kk[i][j]=0.5
        else: 
          if np.average(kk[i][j])>0.25:
            kk[i][j]=0.25
          else:
            kk[i][j]=0.0

Upvotes: 0

Views: 55

Answers (3)

Alain T.
Alain T.

Reputation: 42133

To be more Pythonic, you shouldn't use ranges. You should also only compute the average once (DRY principle):

for row in kk:
  for j,data in enumerate(row):
      average = np.average(data)
      if   average > 0.70: row[j] = 1.0
      elif average > 0.50: row[j] = 0.5
      elif average > 0.25: row[j] = 0.25
      else:                row[j] = 0.0

You could (and should) also avoid changing the nature of rows in the kk list by producing a new list as the output. This can be achieved by leveraging binary searches and list comprehension.

from bisect import bisect_left
A  = [ 0.25,  0.50,   0.70       ]
V  = [ 0.0,   0.25,   0.50,  1.00]
rr = [ V[bisect_left(A,np.average(row))] for row in kk]

Upvotes: 1

Justin
Justin

Reputation: 330

The two major issues I see are the nested loops and the conditional tree. I don't know if this is simpler, but I believe its more elegant. Likely executes faster too. The conditional tree issue is solve using elifs and the nested loops are executed as a generator.


def genny():
    num = 0
    for i in range(len(kk)):
        for j in range(len(kk[i])):
            avg = np.average(kk[i][j])
            kk[i][j] = (yield avg)
            yield

kkgen = genny()
for avg in kkgen:
    if avg > 0.70:
        next_ = 1
    elif avg>0.50:
        next_ = 0.5
    elif avg>0.25:
        next_ = 0.25
    else:
        next_ = 0
    kkgen.send(next_)

Upvotes: 1

blue note
blue note

Reputation: 29099

If it's a regular python N-D array, no, that's the way to do it.

If it's a numpy array, you can use np.ndenumerate.

Upvotes: 1

Related Questions