我有一些二进制数据,我想知道如何将其加载到熊猫中。
我可以以某种方式加载它,指定它的格式,以及各个列的名称吗?
编辑:
格式是
int, int, int, float, int, int[256]
每个逗号分隔代表数据中的一列,即最后 256 个整数是一列。
即使这是一个老问题,我也想知道同样的事情,但我没有看到我喜欢的解决方案。
使用 Python 读取二进制数据时,我发现它numpy.fromfile
比numpy.fromstring
使用 Python struct 模块要快得多。使用上述方法,混合类型的二进制数据可以有效地读入 numpy 数组,只要数据格式是常量并且可以用 numpy 数据类型对象 ( numpy.dtype
) 来描述。
import numpy as np
import pandas as pd
# Create a dtype with the binary data format and the desired column names
dt = np.dtype([('a', 'i4'), ('b', 'i4'), ('c', 'i4'), ('d', 'f4'), ('e', 'i4'),
('f', 'i4', (256,))])
data = np.fromfile(file, dtype=dt)
df = pd.DataFrame(data)
# Or if you want to explicitly set the column names
df = pd.DataFrame(data, columns=data.dtype.names)
编辑:
data.to_list()
。谢谢 fxxcolumns
参数的示例最近我遇到了一个类似的问题,不过结构要大得多。我想我发现使用实用方法DataFrame.from_records改进了 mowen 的答案。在上面的示例中,这将给出:
import numpy as np
import pandas as pd
# Create a dtype with the binary data format and the desired column names
dt = np.dtype([('a', 'i4'), ('b', 'i4'), ('c', 'i4'), ('d', 'f4'), ('e', 'i4'), ('f', 'i4', (256,))])
data = np.fromfile(file, dtype=dt)
df = pd.DataFrame.from_records(data)
就我而言,它显着加快了进程。我认为改进来自不必创建中间 Python 列表,而是直接从 Numpy 结构化数组创建 DataFrame。
这里有一些东西可以帮助您入门。
from struct import unpack, calcsize
from pandas import DataFrame
entry_format = 'iiifi256i' #int, int, int, float, int, int[256]
field_names = ['a', 'b', 'c', 'd', 'e', 'f', ]
entry_size = calcsize(entry_format)
with open(input_filename, mode='rb') as f:
entry_count = os.fstat(f.fileno()).st_size / entry_size
for i in range(entry_count):
record = f.read(entry_size)
entry = unpack(entry_format, record)
entry_frame = dict( (n[0], n[1]) for n in zip(field_names, entry) )
DataFrame(entry_frame)
下面使用编译的结构体,比普通结构体快很多。如上所述,另一种方法是使用 np.fromstring 或 np.fromfile。
import struct, ctypes, os
import numpy as np, pandas as pd
mystruct = struct.Struct('iiifi256i')
buff = ctypes.create_string_buffer(mystruct.size)
with open(input_filename, mode='rb') as f:
nrows = os.fstat(f.fileno()).st_size / entry_size
dtype = 'i,i,i,d,i,i8'
array = np.empty((nrows,), dtype=dtype)
for row in xrange(row):
buff.raw = f.read(s.size)
record = mystruct.unpack_from(buff, 0)
#record = np.fromstring(buff, dtype=dtype)
array[row] = record
df = pd.DataFrame(array)