[英]Combine NumPy Arrays by Reference
我想在O(1)中将两个数组组合成一个新数组。 然后,我想更改此新数组中的值以更改旧数组中的值。
这是在PyGame的surfarray模块的上下文中,该模块没有返回RGBA(n * m * 4)数组的函数 - 仅分别为RGB(n * m * 3)和A(n * m)数组。 理想情况下,我会在O(1)中创建一个新的数组“RGBA”,它引用“RGB”和“A”数组。 改变“RGBA”会改变“RGB”和“A”,因此改变表面。
我不知道这是否可行,因为我想不出用C做的方法。但是,我可以想到一些想法。 例如,可能有一个numpy数组类型封装了一些子数组,并在内部将索引重定向到C级的正确数据。 这没关系。
您可以创建自己的类来管理引用过程,如下例所示。 你应该进一步研究这个问题,包括使用__getslice__
, __add__
, __mul__
等切片功能。
import numpy as np
a1 = np.arange(1,11)
a2 = np.arange(101,111)
class Combiner():
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 = 0
for j,l in enumerate(self.lens):
acc += l
if i<acc:
return self.arrays[j][i-shift]
shift += l
if i<0:
shift = 0
acc = 0
for 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 in enumerate(self.lens):
acc += l
if i<acc:
self.arrays[j][i-shift] = v
return
shift += l
if i<0:
shift = 0
acc = 0
for 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] = 11111
print a1
#[ 1 2 3 4 11111 6 7 8 9 10]
print a2
#[ 101 102 103 104 105 106 107 108 22222 110]
我不确定我是否完全理解这个问题。 根据我的知识,如果你初始化pygame和像这样的表面(在每一行中注意“32”),pygame表面是RGBA(确切地说,BGRA)连续数组:
# display surface
DISP = pygame.display.set_mode((window_w, window_h), 0, 32)
# some surface
window = pygame.Surface((w, h), 0, 32)
另外我建议尽可能使用32位,而不是24位,因为24位表面很难与数组互操作(我使用numpy
来存储和操作图像数据)。
例如,如果我没有弄错的话,24位表面的像素数量必须为4。
如上所述,我不确定你的最后任务是什么,但这就是我如何做到的。
例如,使用openCV
lib加载图像并将其转换为BGRA数组:
# BGR 3d numpy array array (shape = h, w, 3) with image data
img = cv2.imread(filename)
# BGRA 3d numpy array (shape = h, w, 4)
img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
然后这个函数将整个数组数据复制到一个表面,只需要确保它们具有相同的像素大小:
# copy array data into a pygame surface
def copy_arr(surface, myarray):
bv = surface.get_buffer()
bv.write(myarray.tostring(), 0)
但可能是你想做别的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.