Classes as records within an numpy array
I am trying to make a class a record within a numpy array. The piece of code I am working on has the following class within it: class Record: def __init__(self): self.count = 0 self.level = 0 self.list = [] self.max = None self.min = None def add(self, value): self.count += 1 self.level += value if self.max is None: self.max = value else: self.max = max(value, self.max) if self.min is None: self.min = value else: self.min = min(value, self.min) self.list.append(value) when I use this class manually it works as I would expect and does what I want eg: x = Record() x.add(42) x.add(22) x.add(342) x.add(44) x.add(12) x.add(2) for eachitem in x.list: print eachitem 42 22 342 44 12 2 It's Okay to here. When I create the following code: vegetation_matrix = numpy.empty(shape=(x_bins+1,y_bins+1)) for each_line in point_scandata: matrix_x = round_to_value((each_line[0]-x_offset),horizontal_precision) matrix_y = round_to_value((each_line[1]-y_offset),horizontal_precision) vegetation_matrix[matrix_x][matrix_y] = Record() I get an error: Traceback (most recent call last): File "MatrixTo3bynArray.py", line 159, in <module> vegetation_matrix[matrix_x][matrix_y] = Record() SystemError: error return without exception set I would ask the universal what am I doing wrong, but how about I ask in this particular situation, what am I doing wrong? Can anybody guide me through this problem? Regards, David
On Mon, Apr 11, 2011 at 11:00 AM, Sturla Molden <sturla@molden.no> wrote:
Den 11.04.2011 02:01, skrev David Crisp:
Can anybody guide me through this problem?
You must use dtype=object for the array vegetation_matrix.
Thank you. This seemed to remove the error I was having.
You also index vegetation_matrix wrong, use x[i,j] not x[i][j].
Is it a significant problem if I use the x[i][j] method and not the x[i,j] method? Or are we talking about trying to stick with a convention? Regards, David
Den 11.04.2011 03:59, skrev David Crisp:
Is it a significant problem if I use the x[i][j] method and not the x[i,j] method? Or are we talking about trying to stick with a convention?
It is a significant problem. Consider that x[i][j] means ( x[i] )[j]. Then consider that x[i] in your case returns an instance of Record, not ndarray. If you want 2D indexing on an ndarray, it should be written as x[i,j]. A 2D NumPY array is not an array of arrays. If you work with nested Python lists, you should index x[i][j], because x[i] will return a list. Sturla
Den 11.04.2011 04:17, skrev Sturla Molden:
Consider that x[i][j] means ( x[i] )[j]. Then consider that x[i] in your case returns an instance of Record, not ndarray.
Sorry, disregard this. a[i] is the same as a[i,:], which means that a[i,j] and a[i][j] will return the same. But a[i,j] will be faster as you avoid a function call and avoid having to construct a view array for row i. It's getting late :( Sturla
On Mon, Apr 11, 2011 at 11:00 AM, Sturla Molden <sturla@molden.no> wrote:
Den 11.04.2011 02:01, skrev David Crisp:
Can anybody guide me through this problem?
You must use dtype=object for the array vegetation_matrix.
I changed the line which set up the vegetation_matrix to be the following: vegetation_matrix = numpy.empty(shape=(x_bins+1,y_bins+1,),dtype=object) Then I spotted the next problem. In my loop which goes through the raw data and populates the matrix with the required values, I am constantly resetting the Record() to a new record. for each_line in point_scandata: matrix_x = round_to_value((each_line[0]-x_offset),horizontal_precision) matrix_y = round_to_value((each_line[1]-y_offset),horizontal_precision) --> vegetation_matrix[matrix_x,matrix_y] = Record() # This is wrong: Everytime its called it resets the record back to default new.. vegetation_matrix[matrix_x,matrix_y].add(each_line[2] This means that there is always only 1 entry in the record as its always being reset after each iteration. How do I go about setting up the numpy array such that its default record is Record() (Im sure this IS a brain fade as It seems really familliar) Regards, David
On Mon, Apr 11, 2011 at 1:17 PM, David Crisp <david.crisp@gmail.com> wrote:
On Mon, Apr 11, 2011 at 11:00 AM, Sturla Molden <sturla@molden.no> wrote:
Den 11.04.2011 02:01, skrev David Crisp:
Can anybody guide me through this problem?
I dont know how acceptable it is to answer your own question :P here goes: TO some extent I have solved my problem, But I am unsure if it is the correct way of solving it: for each_line in point_scandata: matrix_x = round_to_value((each_line[0]-x_offset),horizontal_precision) matrix_y = round_to_value((each_line[1]-y_offset),horizontal_precision) if vegetation_matrix[matrix_x,matrix_y] == None: vegetation_matrix[matrix_x,matrix_y] = Record() vegetation_matrix[matrix_x,matrix_y].add(each_line[2]) I added the IF check. If vegetation_matrix[matrix_x,matrix_y] is still equal to None then that means the record for that grid cell has not been created yet. So if it IS none then simply create a record. If vegetation_matrix[matrix_x,matrix_y] is NOT None then the only other value it could be is Record (Major Assumption that nobody else has fiddled with the code) and so simply add a new value to the record with the appropriate value. It works but is it the correct way of doing things... Regards, David
On 04/11/2011 05:40 AM, David Crisp wrote:
On Mon, Apr 11, 2011 at 1:17 PM, David Crisp <david.crisp@gmail.com> wrote:
On Mon, Apr 11, 2011 at 11:00 AM, Sturla Molden <sturla@molden.no> wrote:
Den 11.04.2011 02:01, skrev David Crisp:
Can anybody guide me through this problem?
I dont know how acceptable it is to answer your own question :P here goes:
TO some extent I have solved my problem, But I am unsure if it is the correct way of solving it:
for each_line in point_scandata: matrix_x = round_to_value((each_line[0]-x_offset),horizontal_precision) matrix_y = round_to_value((each_line[1]-y_offset),horizontal_precision) <---- vertical_precision? if vegetation_matrix[matrix_x,matrix_y] == None: vegetation_matrix[matrix_x,matrix_y] = Record() vegetation_matrix[matrix_x,matrix_y].add(each_line[2]) Hi, you should initialize the matrix when creating it. What about vegeration_matrix = numpy.array([[Record() for _ in xrange(x_bins+1)] for _ in xrange(y_bins+1)]) Then you could avoid the ugly if.
A more general question: why do you want to use numpy object arrays at all? You are not using any array operatations with your Record objects. The numpy array of objects is equivalent to a two-dimensional list. You could use a normal Python list just as well: vegetation_matrix = [[Record() for _ in xrange(x_bins+1)] for _ in xrange(y_bins+1)] vegetation_matrix[4][3].add(11) Best, Zbyszek
participants (3)
-
David Crisp
-
Sturla Molden
-
Zbigniew Jędrzejewski-Szmek