Reputation: 1097
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
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
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