Я пытаюсь прочитать содержимое CSV-файла, содержащего, как мне кажется, числа с плавающей запятой одинарной точности IEEE 754 в десятичном формате.
По умолчанию они читаются как int64. Если я укажу тип данных с чем-то вроде dtype = {'col1' : np.float32}
, dtype будет правильно отображаться как float32, но это будут те же значения, что и float, а не int, ie. 1079762502
становится 1.079763e+09
вместо 3.435441493988037
.
Мне удалось выполнить преобразование отдельных значений одним из следующих способов:
from struct import unpack
v = 1079762502
print(unpack('>f', v.to_bytes(4, byteorder="big")))
print(unpack('>f', bytes.fromhex(str(hex(v)).split('0x')[1])))
Что дает
(3.435441493988037,)
(3.435441493988037,)
Однако я не могу реализовать это векторизованным способом с помощью pandas:
import pandas as pd
from struct import unpack
df = pd.read_csv('experiments/test.csv')
print(df.dtypes)
print(df)
df['col1'] = unpack('>f', df['col1'].to_bytes(4, byteorder="big"))
#df['col1'] = unpack('>f', bytes.fromhex(str(hex(df['col1'])).split('0x')[1]))
print(df)
Выдает следующую ошибку
col1 int64
dtype: object
col1
0 1079762502
1 1079345162
2 1078565306
3 1078738012
4 1078635652
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-8-c06d0986cc96> in <module>
7 print(df)
8
----> 9 df['col1'] = unpack('>f', df['col1'].to_bytes(4, byteorder="big"))
10 #df['col1'] = unpack('>f', bytes.fromhex(str(hex(df['col1'])).split('0x')[1]))
11
~/anaconda3/envs/test/lib/python3.7/site-packages/pandas/core/generic.py in __getattr__(self, name)
5177 if self._info_axis._can_hold_identifiers_and_holds_name(name):
5178 return self[name]
-> 5179 return object.__getattribute__(self, name)
5180
5181 def __setattr__(self, name, value):
AttributeError: 'Series' object has no attribute 'to_bytes'
Или, если я попробую второй способ, TypeError: 'Series' object cannot be interpreted as an integer
Я нахожусь в пределах моих Python знаний здесь, я полагаю, я мог бы перебирать каждую отдельную строку, преобразовывать в шестнадцатеричный, затем в строку, затем удалять 0x, распаковывать и хранить. Но это кажется очень запутанным и уже занимает несколько секунд для небольших наборов данных, не говоря уже о сотнях тысяч записей. Мне здесь не хватает чего-то простого, есть ли лучший способ сделать это?