Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Numpy将非连续数组的连续部分视为较大的数据类型_Python_Arrays_Numpy_Memory Layout - Fatal编程技术网

Python Numpy将非连续数组的连续部分视为较大的数据类型

Python Numpy将非连续数组的连续部分视为较大的数据类型,python,arrays,numpy,memory-layout,Python,Arrays,Numpy,Memory Layout,我试图从一个超长字符数组生成一个三元数组(即连续的三个字母组合): # data is actually load from a source file a = np.random.randint(0, 256, 2**28, 'B').view('c') 由于复制效率不高(并且会产生缓存丢失等问题),因此我使用跨步技巧直接生成了三元图: tri = np.lib.stride_tricks.as_strided(a, (len(a)-2,3), a.strides*2) 这将生成一个具有形

我试图从一个超长字符数组生成一个三元数组(即连续的三个字母组合):

# data is actually load from a source file
a = np.random.randint(0, 256, 2**28, 'B').view('c')
由于复制效率不高(并且会产生缓存丢失等问题),因此我使用跨步技巧直接生成了三元图:

tri = np.lib.stride_tricks.as_strided(a, (len(a)-2,3), a.strides*2)
这将生成一个具有形状
(2**28-2,3)
的三角图列表,其中每一行都是一个三角图。现在,我想将三角形转换为字符串列表(即
S3
),以便numpy更“合理”地显示它(而不是单个字符)

它给出了例外情况:

ValueError: To change to a dtype of a different size, the array must be C-contiguous
我知道为了创建一个有意义的视图,通常数据应该是连续的,但是这个数据在“应该在哪里”是连续的:每三个元素都是连续的

因此,我想知道如何
将非连续
np.ndarray
中的连续部分视为较大的数据类型?一个更“标准”的方式会更好,而黑客的方式也是受欢迎的。似乎我可以用
np.lib.stride\u技巧自由设置
shape
stride
,但是我不能强迫
dtype
成为某种东西,这就是这里的问题

编辑

非连续数组可以通过简单的切片生成。例如:

np.empty((8, 4), 'uint32')[:, :2].view('uint64')

将抛出上面相同的异常(而从内存的角度来看,我应该能够做到这一点)。这种情况比我上面的例子更常见。

如果您可以访问从中派生非连续数组的连续数组,通常应该可以绕过此限制

例如,您的三角形可以如下获得:

>>> a = np.random.randint(0, 256, 2**28, 'B').view('c')
>>> a
array([b')', b'\xf2', b'\xf7', ..., b'\xf4', b'\xf1', b'z'], dtype='|S1')
>>> np.lib.stride_tricks.as_strided(a[:0].view('S3'), ((2**28)-2,), (1,))
array([b')\xf2\xf7', b'\xf2\xf7\x14', b'\xf7\x14\x1b', ...,
       b'\xc9\x14\xf4', b'\x14\xf4\xf1', b'\xf4\xf1z'], dtype='|S3')
事实上,这个示例演示了我们所需要的只是内存缓冲区底部的一个连续的“存根”来进行视图转换,因为
as_crossed
不做很多检查,我们基本上可以自由地做任何我们喜欢的事情

似乎我们总是可以通过切片到大小为0的数组来获得这样的存根。第二个例子是:

>>> X = np.empty((8, 4), 'uint32')[:, :2]
>>> np.lib.stride_tricks.as_strided(X[:0].view(np.uint64), (8, 1), X.strides)
array([[140133325248280],
       [             32],
       [       32083728],
       [       31978800],
       [              0],
       [       29686448],
       [             32],
       [       32362720]], dtype=uint64)

关于
np.ascontiguousarray(tri).view('S3')
?@AndyK我相信OP希望避免这种强制复制。任何数组的数据缓冲区都是连续的-一个长的低级别字节数组。但该缓冲区的视图可能不是“C”连续的。在
[:,:2]
的情况下,有2个元素,然后是一个间隙,还有2个元素,等等。请查看
标志
。显然,
视图
没有进行额外的步骤来验证每个
uint64
所需的8个字节是否是连续的。这很有趣,尽管很难理解它为什么工作+1
view
ing一个大小为零的数组很有趣!我在考虑以某种方式创建一个正确的数据类型数组(如查看字节时的大小为1的数组),但大小为零的视图肯定更有用!
>>> X = np.empty((8, 4), 'uint32')[:, :2]
>>> np.lib.stride_tricks.as_strided(X[:0].view(np.uint64), (8, 1), X.strides)
array([[140133325248280],
       [             32],
       [       32083728],
       [       31978800],
       [              0],
       [       29686448],
       [             32],
       [       32362720]], dtype=uint64)