Как мне интерпретировать двоичный файл массива numpy?

#python #numpy #numpy-ndarray

#python #numpy #numpy-ndarray

Вопрос:

Здесь описывается структура PyArrayObject .

В сеансе Python у меня есть следующее:

 >>> t_ar1 = np.linspace(0, 15, 16).reshape((4, 4))
>>> print(hex_fmt(string_at(id(t_ar1), 80).hex()))
0100000000000000
40b06eecbd7f0000
3053b973bf550000
02000000ffffffff
70eaa873bf550000
80eaa873bf550000
50c826adbd7f0000
00b66eecbd7f0000
01050000322c2033
0000000000000000
  

Насколько я понимаю, третья строка является указателем на фактические данные массива. Просматривая там данные, я нахожу

 >>> print(hex_fmt(string_at(id(0x55bf73b95330), 96).hex()))
0200000000000000
4049a801be7f0000
0200000000000000
3053b933fd560100
489601adbd7f0000
10ab27adbd7f0000
0000000000000000
0000000000000000
d09501adbd7f0000
b0aa27adbd7f0000
0000000000000000
0000000000000000
  

Здесь я ожидаю увидеть числа с плавающей запятой 0.0 — 15.0 где-нибудь. Однако, похоже, я не могу их найти. Что здесь происходит?

Комментарии:

1. Что такое hex_fmt и string_at ?

2. string_at из модуля ctypes. hex_fmt просто красиво — выводит шестнадцатеричное значение (это неважно).

Ответ №1:

string_at из ctypes модуля.

Чтобы получить данные непосредственно из массива numpy, вам нужно интерпретировать байтовую строку (полученную с помощью string_at ) как массив чисел с плавающей запятой (8-байтовые удвоения). Итак, нам нужно использовать модуль struct для интерпретации байтовой строки как массива чисел:

 from ctypes import string_at
import numpy as np
import struct # needed to unpack data

t_ar1 = np.linspace(0, 15, 16).reshape((4, 4))
struct.unpack('16d', string_at(t_ar1.__array_interface__['data'][0], size=8 * 16))
  

(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
13.0, 14.0, 15.0)

Ответ №2:

Это должно быть

 string_at(0x55bf73b95330, 96)
  

Вместо того, что у меня было,

 string_at(id(0x55bf73b95330), 96)
  

В этом случае вы получите

 >>> print(hex_fmt(string_at(0x55bf73b95330, 96).hex()))
0000000000000000
000000000000f03f
0000000000000040
0000000000000840
0000000000001040
0000000000001440
0000000000001840
0000000000001c40
0000000000002040
0000000000002240
0000000000002440
0000000000002640
  

Как и ожидалось.