【问题标题】:How to read multiple data types from memoryview in Python?如何从 Python 中的 memoryview 读取多种数据类型?
【发布时间】:2020-12-14 08:29:21
【问题描述】:

我正在读取传感器数据,它有 6 列,前四列是 32 位浮点数,后两列是无符号整数。下面是如何将其转换为 numpy 数组:

data = np.frombuffer(sensor_data.raw_data, dtype=np.dtype('float32')).reshape([-1, 6])
data = data[:, :5]

int_data = np.frombuffer(sensor_data.raw_data, dtype=np.dtype('uint')).reshape([-1, 6])
int_data = int_data[:, 4:6]

这似乎不是最有效的方法。有没有办法读取多种数据类型或将最后两列从float32 转换回字节,然后转换为uint

【问题讨论】:

  • 如果您明确说明文件中每个无符号整数使用多少字节,则更容易创建正确的解决方案。 np.dtype('uint') 在某些平台上可能是 4 个字节,而在其他平台上可能是 8 个字节。

标签: python numpy memory floating-point unsigned-integer


【解决方案1】:

如果您的 2 个负载有效,则无符号整数必须是 32 位。

我们可以构造一个具有复合 dtype 的等效结构化数组:

In [58]: dt = np.dtype([('f0','f4',4),('f1','uint32',2)])                       
In [59]: arr = np.zeros(5, dt)                                                  
In [60]: arr['f0'] = np.random.rand(5,4)                                        
In [61]: arr['f1'] = np.random.randint(0,100,(5,2))                             
In [62]: arr                                                                    
Out[62]: 
array([([0.38565257, 0.36662674, 0.5530039 , 0.17866635], [39,  3]),
       ([0.12109676, 0.60092086, 0.6555444 , 0.06968965], [18, 96]),
       ([0.7082187 , 0.48962796, 0.4019332 , 0.19190358], [26, 81]),
       ([0.34053752, 0.35870123, 0.22802468, 0.33509415], [48, 52]),
       ([0.45730132, 0.38697603, 0.18952931, 0.90458447], [ 3, 40])],
      dtype=[('f0', '<f4', (4,)), ('f1', '<u4', (2,))])

并创建一个数据缓冲区:

In [63]: astr = arr.tobytes()                                                   

您的负载与该缓冲区一起工作:

In [64]: data = np.frombuffer(astr, 'float32').reshape(-1,6)                    
In [65]: data[:,:4]                                                             
Out[65]: 
array([[0.38565257, 0.36662674, 0.5530039 , 0.17866635],
       [0.12109676, 0.60092086, 0.6555444 , 0.06968965],
       [0.7082187 , 0.48962796, 0.4019332 , 0.19190358],
       [0.34053752, 0.35870123, 0.22802468, 0.33509415],
       [0.45730132, 0.38697603, 0.18952931, 0.90458447]], dtype=float32)
In [66]: data = np.frombuffer(astr, 'uint32').reshape(-1,6)                     
In [67]: data[:,4:]                                                             
Out[67]: 
array([[39,  3],
       [18, 96],
       [26, 81],
       [48, 52],
       [ 3, 40]], dtype=uint32)

但我们也可以使用复合 dtype 来加载它:

In [68]: data = np.frombuffer(astr, dt)                                         
In [69]: data['f0']                                                             
Out[69]: 
array([[0.38565257, 0.36662674, 0.5530039 , 0.17866635],
       [0.12109676, 0.60092086, 0.6555444 , 0.06968965],
       [0.7082187 , 0.48962796, 0.4019332 , 0.19190358],
       [0.34053752, 0.35870123, 0.22802468, 0.33509415],
       [0.45730132, 0.38697603, 0.18952931, 0.90458447]], dtype=float32)
In [70]: data['f1']                                                             
Out[70]: 
array([[39,  3],
       [18, 96],
       [26, 81],
       [48, 52],
       [ 3, 40]], dtype=uint32)
       

该复合数据类型也适用于“uint64”。

我们还可以使用viewfloat32负载中获取uint32

In [84]: data = np.frombuffer(astr, 'float32').reshape(-1,6)                    
In [86]: data[:,4:].view('uint32')                                              
Out[86]: 
array([[39,  3],
       [18, 96],
       [26, 81],
       [48, 52],
       [ 3, 40]], dtype=uint32)

(或带有视图的 uint 中的浮点数)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2016-05-13
    • 1970-01-01
    • 2019-01-04
    • 2021-04-05
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多