[英]Can I efficiently create a pandas data frame from semi-structured binary data?
我需要将大型二进制文件转换为nx 3数组。 数据是由(x,y,time)坐标定义的一系列图像帧。 每个帧使用两个32位整数来定义nx 3个维度,并使用n个三位16位整数来定义(x,y,time)值。 结果是一个二进制结构,如下所示:
int32, int32, uint16, uint16, uint16, ..., int32, int32, uint16, uint16, uint16
等。
我的第一次尝试是将二进制数据转换为一维数组,然后将所需的部分添加到数据帧中。 当前数据已经过排序,可以在没有两个int32
值的情况下重建帧分隔,因此可以在必要时将其丢弃。 如果不是这种情况,则可以通过在将每个帧添加到最终数据帧之前分别对其进行排序来达到相同的效果。
import numpy as np
import pandas as pd
def frame_extract(index):
n = data[index]
subarray=data[index+4:index+(3*n+4)]
subarray=np.reshape(subarray, (len(subarray)/3,3))
frame = pd.DataFrame(data=subarray, columns=['x','y','t'])
return frame
def indexer(index):
n = data[index]
new_index = index+(3*n+4)
return new_index
data = np.fromfile('file.bin', dtype='<u2')
framedata = pd.DataFrame()
index = 0
while index <= len(data)-1:
framedata = framedata.append(frame_extract(index), ignore_index=True)
index = indexer(index)
print(framedata)
上面的方法可以工作,但是while循环非常慢,特别是与以下结构化方法相比时,如果int32
值不妨碍,它将很好地工作(并且快几个数量级):
dt = np.dtype([('x', '<u2'), ('y', '<u2'), ('time', '<u2')])
data = np.fromfile("file.bin", dtype=dt)
df = pd.DataFrame(data.tolist(), columns=data.dtype.names)
有没有更有效的方法来解决这个问题? 如果是这样,那么在解压缩二进制数据时,或者在将其转换为整数之后,这样做会更容易吗?
我目前正在考虑使用生成器将二进制文件作为一系列块读取(即,使用两个32位整数来确定我需要的16位整数块有多大),但是我还不熟悉这些知识足以说明这是否是正确的方法。
每次追加到数据框时,您都将整个内容复制到内存中的新位置。 您将要使用最终大小完整的numpy数组初始化数据帧,然后在用成像数据填充数据时使用iloc()等索引到该帧。
另外,您是否有使用熊猫数据框存储成像数据的特定原因? 他们并不是真的要这么做...
count
参数通过允许np.fromfile
利用int32
值定义的结构来简化此操作。 以下for
循环分别创建每个图像帧:
f = open('file.bin', 'rb')
for i in np.arange(1,15001,1):
m, n = np.fromfile(f, dtype='<i', count=2)
frame = np.reshape(np.fromfile(f, dtype='<u2', count=m*n), (m, n))
可以使用以下方法将每个框架添加到列表中并转换为数据框架:
f = open('file.bin', 'rb')
xyt_data = list()
for i in np.arange(1,15001,1):
m, n = np.fromfile(f, dtype='<i', count=2)
frame = np.reshape(np.fromfile(f, dtype='<u2', count=m*n), (m, n))
xyt_data.append(frame)
df = pd.DataFrame(np.vstack(xyt_data), columns=['x','y','t'])
结果比原始问题中描述的版本快三个数量级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.