python - Numpy将非连续数组的连续部分视为更大尺寸的dtype
问题描述
我试图从一个超长字符数组中生成一个三元组(即连续三字母组合):
# 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 更“合理地”显示它(而不是单个字符)。
tri = tri.view('S3')
它给出了例外:
ValueError: To change to a dtype of a different size, the array must be C-contiguous
我通常理解数据应该是连续的,以便创建有意义的视图,但是这些数据在“应该在哪里”是连续的:每三个元素都是连续的。
所以我想知道如何将view
非连续部分连续np.ndarray
作为更大尺寸的 dtype?更“标准”的方式会更好,同时也欢迎使用骇人听闻的方式。似乎我可以自由地设置shape
,但我不能强迫成为某事,这就是这里的问题。stride
np.lib.stride_tricks.as_strided
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_strided
不做很多检查,我们基本上可以自由地做任何我们喜欢的事情。
似乎我们总是可以通过切片到大小为 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)
推荐阅读
- excel - 使用固定宽度设置将文本自动分列?
- centos6 - 将 Centos 6.10 升级到 6.9
- javascript - 用外部函数反应 componentdidmount 返回状态
- ios - Objective-C 中的策略模式
- matlab - 给定 y 值的 X 值
- java - 如何调用另一个类中的 ArrayList 上的方法?
- java - 如何同步运行两个异步任务
- javascript - Node.js - 获取单个 XML 值
- python - Udacity 计算机科学简介:第 7 课练习 2
- jsf - Atmosphere 框架不适用于带有 payara 的 Openshift