numpy 数组元数据更改
numpy array metadata change
我知道 numpy 在连续内存中存储数字。那么可以拿
a = np.array([127,127,127,127,127,127,127,127], dtype=np.uint8)
'a'的二进制表示都是全1
对此:
b = np.array([72057594037927935], dtype=np.uint64)
以及从 b->a 返回。
二进制表示全部为1,但是元素的数量组合为一个64位int
在 Numpy 中表示应该相同,只有元数据应该改变。
这听起来像是一项跨步技巧的工作,但我的最佳猜测是:
np.lib.stride_tricks.as_strided(a, shape=(1,), strides=(8,8))
和
np.lib.stride_tricks.as_strided(b, shape=(8,), strides=(1,8))
只得到 ValueError:步幅长度和形状不匹配
这里只需要阅读,所以我没有妄想我需要更改数据。
如果您想重新解释 数组中的现有数据,您需要numpy.ndarray.view
。这是 .astype
和 .view
之间的主要区别(即前者转换为保留 values 的新类型,而后者保持相同的内存和变化它是如何解释的):
import numpy as np
a = np.array([127,127,127,127,127,127,127,127], dtype=np.uint8)
b = a.view(np.uint64)
print(a)
print(b)
print(b.view(np.uint8))
这输出
[127 127 127 127 127 127 127 127]
[9187201950435737471]
[127 127 127 127 127 127 127 127]
请注意 127
在其二进制模式中有一个前导零,所以它 不是 全一,这就是我们在 b
中得到的值的原因与您期望的不同:
>>> bin(b[0])
'0b111111101111111011111110111111101111111011111110111111101111111'
>>> bin(72057594037927935)
'0b11111111111111111111111111111111111111111111111111111111'
您似乎假设的是一组 uint7
个位的值...
无论如何,.view
最好的部分是将使用完全相同的内存块,除非您明确复制:
>>> b.base is a
True
推论当然是变异 b
会影响 a
:
>>> b += 3
>>> a
array([130, 127, 127, 127, 127, 127, 127, 127], dtype=uint8)
要控制字节顺序,您需要使用 string-valued dtype specifications,即 a.view('<u8')
(小端)或 a.view('>u8')
(大端)。我们可以用它来重现您问题中的错误号码:
>>> a2 = np.array([0] + [255] * 7, dtype=np.uint8)
... a2.view('>u8')
array([72057594037927935], dtype=uint64)
我知道 numpy 在连续内存中存储数字。那么可以拿
a = np.array([127,127,127,127,127,127,127,127], dtype=np.uint8)
'a'的二进制表示都是全1
对此:
b = np.array([72057594037927935], dtype=np.uint64)
以及从 b->a 返回。
二进制表示全部为1,但是元素的数量组合为一个64位int 在 Numpy 中表示应该相同,只有元数据应该改变。
这听起来像是一项跨步技巧的工作,但我的最佳猜测是:
np.lib.stride_tricks.as_strided(a, shape=(1,), strides=(8,8))
和
np.lib.stride_tricks.as_strided(b, shape=(8,), strides=(1,8))
只得到 ValueError:步幅长度和形状不匹配
这里只需要阅读,所以我没有妄想我需要更改数据。
如果您想重新解释 数组中的现有数据,您需要numpy.ndarray.view
。这是 .astype
和 .view
之间的主要区别(即前者转换为保留 values 的新类型,而后者保持相同的内存和变化它是如何解释的):
import numpy as np
a = np.array([127,127,127,127,127,127,127,127], dtype=np.uint8)
b = a.view(np.uint64)
print(a)
print(b)
print(b.view(np.uint8))
这输出
[127 127 127 127 127 127 127 127]
[9187201950435737471]
[127 127 127 127 127 127 127 127]
请注意 127
在其二进制模式中有一个前导零,所以它 不是 全一,这就是我们在 b
中得到的值的原因与您期望的不同:
>>> bin(b[0])
'0b111111101111111011111110111111101111111011111110111111101111111'
>>> bin(72057594037927935)
'0b11111111111111111111111111111111111111111111111111111111'
您似乎假设的是一组 uint7
个位的值...
无论如何,.view
最好的部分是将使用完全相同的内存块,除非您明确复制:
>>> b.base is a
True
推论当然是变异 b
会影响 a
:
>>> b += 3
>>> a
array([130, 127, 127, 127, 127, 127, 127, 127], dtype=uint8)
要控制字节顺序,您需要使用 string-valued dtype specifications,即 a.view('<u8')
(小端)或 a.view('>u8')
(大端)。我们可以用它来重现您问题中的错误号码:
>>> a2 = np.array([0] + [255] * 7, dtype=np.uint8)
... a2.view('>u8')
array([72057594037927935], dtype=uint64)