jorgehumberto
jorgehumberto

Reputation: 1097

Atributes of class in numpy array

I have a class like:

class MyClass:
 def __init__( self, params):
   self.A = params[0]
   self.B = params[1]
   self.C = params[2]

and a numpy array built from instances of this class:

import numpy as np


ArrayA = np.empty((3,4),dtype = object)

for ii in range(3):
  for jj in range(4):
    ArrayA[ii,jj] = MyClass(np.random.rand(3))

I want to retrieve "MyClass.B" for ArrayA where "MyClass.A" is minimum, so I did:

WhereMin = np.where(ArrayA[:,:].A)
MinB = ArrayA[WhereMin].B

but that does not work. Any ideas?

EDIT: When I run the above code I get the following error:

----> WhereMin = np.nanmin(ArrayA[:,:].A)
AttributeError: 'numpy.ndarray' object has no attribute 'A'

When I would expect to get an array of indices to use in "MinB".

Possible Solution I found a possible solution to my problem:

Min = np.nanmin([[x.A for x in XX] for XX in ArrayA])
XXX = [[x for x in XX if x.A == Min] for XX in ArrayA]
MinB = [XX for XX in XXX if XX != [] ][0][0].B

Might not be too elegant, but does the job. Thank you all!

Upvotes: 0

Views: 174

Answers (2)

mtadd
mtadd

Reputation: 2555

You can create a structured numpy array. Pass dtype a list of tuples of field name and data type. You can then access the complete array of a given field by indexing the array by the field name. To rework your example:

ArrayA = np.zeros((3,4),dtype=[('A','<f4'),('B','<f4'),('C','<f4')])

for ii in range(3):
  for jj in range(4):
    ArrayA[ii,jj] = np.random.rand(3)

minA = ArrayA['A'].min()
WhereMin = np.where(a['A'] == minA)
MinB = ArrayA[WhereMin]['B']

Upvotes: 0

SethMMorton
SethMMorton

Reputation: 48815

The .A attribute belongs to each individual element of ArrayA, not to the array as a whole. So, ArrayA[0,0].A is valid, because ArrayA[0,0] points to an instance of MyClass, but ArrayA[:,:] returns a copy of the original ndarray.

I would consider reorganizing your data so that you keep everything you want in the .A attribute in a single numpy array, and everything in .B in a single numpy array, etc. That would have two advantages, 1) you would be able to use where, and 2) your numpy arrays would be of dtype=float (you lose the advantage of numpy if you have to use dtype=object).

Upvotes: 1

Related Questions