Вот пример использования вашего dtype с использованием строки байтов в памяти вместо файла:
In [279]: dt=np.dtype([('a','uint'),('b','uint'),('c','uint'),('d','uint'),('e','uint'),('f','
...: uint'),('g',float),('h',np.float32)])
In [280]:
In [280]: x = np.ones((3,),dt)
In [281]: x
Out[281]:
array([(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.),
(1, 1, 1, 1, 1, 1, 1., 1.)],
dtype=[('a', '<u8'), ('b', '<u8'), ('c', '<u8'), ('d', '<u8'), ('e', '<u8'), ('f', '<u8'), ('g', '<f8'), ('h', '<f4')])
In [282]: x.tostring()
Out[282]: b'\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x80?\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x80?\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x80?'
In [283]: np.frombuffer(x.tostring(), dtype=dt)
Out[283]:
array([(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.),
(1, 1, 1, 1, 1, 1, 1., 1.)],
dtype=[('a', '<u8'), ('b', '<u8'), ('c', '<u8'), ('d', '<u8'), ('e', '<u8'), ('f', '<u8'), ('g', '<f8'), ('h', '<f4')])
То, что uint
действительно должно быть uint8
- 1-байтовое целое число без знака, а неполная 8-байтовая версия?
In [300]: dt1=np.dtype([('a','uint8'),('b','uint8'),('c','uint8'),('d','uint8'),('e','uint8'),
...: ('f','uint8'),('g',float),('h',np.float32)])
In [301]: y = np.ones((10,),dt1)
itemsize
для двух массивов совершенно различна:
In [302]: x.itemsize
Out[302]: 60
In [303]: y.itemsize
Out[303]: 18
Но если бы общий размер был правильным, то любой из них мог бы быть прочитан другим (10 * 18 == 3 * 60):
In [304]: np.frombuffer(y.tostring(), dtype=dt1)
Out[304]:
array([(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.),
(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.),
(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.),
(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.),
(1, 1, 1, 1, 1, 1, 1., 1.), (1, 1, 1, 1, 1, 1, 1., 1.)],
dtype=[('a', 'u1'), ('b', 'u1'), ('c', 'u1'), ('d', 'u1'), ('e', 'u1'), ('f', 'u1'), ('g', '<f8'), ('h', '<f4')])
Несоответствие - это dtypes:
In [305]: np.frombuffer(y.tostring(), dtype=dt)
Out[305]:
array([( 1103823438081, 70300024700928, 72340172838092672, 4607182418800017408, 72340173886586880, 257, 7.8598509e-304, 2.3694278e-38),
(4607182418800017408, 72340173886586880, 257, 72408888003018736, 16843009, 4575657222481117184, 5.4536124e-312, 0.0000000e+00),
( 72408888003018736, 16843009, 4575657222481117184, 1103823438081, 70300024700928, 72340172838092672, 1.0000000e+000, 1.0000000e+00)],
dtype=[('a', '<u8'), ('b', '<u8'), ('c', '<u8'), ('d', '<u8'), ('e', '<u8'), ('f', '<u8'), ('g', '<f8'), ('h', '<f4')])
При несовпадении в dtypes мы можем получить ошибку:
ValueError: buffer size must be a multiple of element size
Все же случайное несоответствие в dtypes может объяснить чтение fromfile
, которое запускается, но выдает неправильные значения, особенно те, которые выглядят не так.
На основании вашего комментария я написал:
In [347]: dt1=np.dtype([('a','u4'),('b','u4'),('c','u4'),('d','u4'),('e','u4'),('f','u4'),('g','f4')])
На данный момент я пропускаю h
.
Теперь создайте массив с несколькими записями:
In [351]: x=np.ones((3,),dt1); x['g'][0]=10
In [352]: x
Out[352]:
array([(1, 1, 1, 1, 1, 1, 10.), (1, 1, 1, 1, 1, 1, 1.),
(1, 1, 1, 1, 1, 1, 1.)],
dtype=[('a', '<u4'), ('b', '<u4'), ('c', '<u4'), ('d', '<u4'), ('e', '<u4'), ('f', '<u4'), ('g', '<f4')])
Напишите его, а затем загрузите только один счет:
In [353]: np.frombuffer(x.tostring(), count=1,dtype=dt1)
Out[353]:
array([(1, 1, 1, 1, 1, 1, 10.)],
dtype=[('a', '<u4'), ('b', '<u4'), ('c', '<u4'), ('d', '<u4'), ('e', '<u4'), ('f', '<u4'), ('g', '<f4')])
Я бы предложил использовать dt1
и использовать его для загрузки только одной записи.Посмотрите, выглядят ли значения разумными.
Я пропустил h
, потому что вы описываете его как 'h' is a float array such that it is 4*g bytes long
.Если «g» - это число с плавающей запятой, эта длина плохо определена;это должно быть int какого-то рода.
Если вы оставили fn
открытым в этот момент, тогда np.fromfile(fn, '<f4', count=n)
может работать для загрузки этого массива 'h'.Я бы начал с небольшого n
, чтобы посмотреть, является ли это многообещающим, а позже попробуйте большее значение или открытый конец -1
.
Другими словами, ваше описание звучит так, как будто файл содержит заголовокфиксированного размера, а затем блок плавающего размера.