Skip to content Skip to sidebar Skip to footer

Combine Numpy Arrays By Reference

I want to combine two arrays into a new array in O(1). Then, I want to change the values in this new array to change the values in the old arrays. This is in the context of PyGame

Solution 1:

You can create your own class that will manage the referencing procedures, as shown in the example below. You should work further on this to include slicing capabilities with __getslice__, __add__, __mul__, and so forth.

import numpy as np
a1 = np.arange(1,11)
a2 = np.arange(101,111)
classCombiner():
    def__init__(self, *args):
        self.arrays = [arg for arg in args]
        self.lens = [len(arg) for arg in args]
    def__getitem__(self,i):
        if i >=0:
            shift = 0
            acc = 0for j,l inenumerate(self.lens):
                acc += l
                if i<acc:
                    return self.arrays[j][i-shift]
                shift += l
        if i<0:
            shift = 0
            acc = 0for j in xrange(len(self.lens)-1,-1,-1):
                l = self.lens[j]
                acc -= l
                if i>=acc:
                    return self.arrays[j][i+shift]
                shift += l

    def__setitem__(self,i,v):
        if i >=0:
            shift = 0
            acc = 0.for j,l inenumerate(self.lens):
                acc += l
                if i<acc:
                    self.arrays[j][i-shift] = v
                    return
                shift += l
        if i<0:
            shift = 0
            acc = 0for j in xrange(len(self.lens)-1,-1,-1):
                l = self.lens[j]
                acc -= l
                if i>=acc:
                    self.arrays[j][i+shift] = v
                    return
                shift += l

a3 = Combiner(a1,a2)
print a3[-10]
# 101
a3[-2] = 22222
a3[ 4] = 11111print a1
#[    1     2     3     4 11111     6     7     8     9    10]print a2
#[  101   102   103   104   105   106   107   108 22222   110]

Solution 2:

I am not sure I've completely understood the question. From my knowledge, pygame surfaces are in RGBA (to be exact, BGRA) contiguous arrays if you init pygame and surfaces like this (note "32" in each line):

# display surfaceDISP = pygame.display.set_mode((window_w, window_h), 0, 32)
# some surfacewindow = pygame.Surface((w, h), 0, 32) 

Also I would recommend to use 32 bit when possible, and not 24 bit, because 24 bit surfaces are hard to interoperate with arrays (I use numpy for storing and manipulating image data). For example, a 24 bit surface must have amount of pixel dividable by 4, if I am not mistaken.

As said, I am not sure what is your final task, but here is how I do it. E.g. load an image with openCV lib and convert it to BGRA array:

# BGR 3d numpy array array (shape = h, w, 3) with image dataimg = cv2.imread(filename)
# BGRA 3d numpy array (shape = h, w, 4) img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)

Then this function copies whole array data into a surface, just need to be sure they have same pixel size:

# copy array data into a pygame surface
def copy_arr(surface, myarray):
    bv = surface.get_buffer()
    bv.write(myarray.tostring(), 0)

But it can be that you wanted to do something else.

Post a Comment for "Combine Numpy Arrays By Reference"