【问题标题】:numpy array metadata changenumpy 数组元数据更改
【发布时间】:2020-02-27 10:22:56
【问题描述】:

我知道 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:步幅长度和形状不匹配

这只需要只读,所以我没有妄想我需要更改数据。

【问题讨论】:

  • @Divakar uint7 一位,显然 :)
  • 另见 a.tobytes() 包含 \x7f 而不是 \xff 块。
  • 复制错误 0b1111111 (7 x1's *8) 我一开始就缺少前导零。但就是这样......我想知道我是否会改变这一点。

标签: python numpy metadata stride


【解决方案1】:

如果您想重新解释数组中的现有数据,您需要numpy.ndarray.view。这是.astype.view 之间的主要区别(即前者转换为新类型并保留,而后者保持相同的内存并更改其解释方式):

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2017-03-04
    • 1970-01-01
    • 2020-02-29
    • 2018-02-01
    • 2022-11-12
    相关资源
    最近更新 更多