我在非常大的文件中有顺序(打包的c-struct)格式的timeseries数据.每个 struct 都按一定顺序包含K个不同类型的字段.文件本质上是这些 struct 的数组(按行).我希望能够mmap文件并将每个字段映射到一个numpy数组(或另一种形式),在这个数组中,数组可以识别出数据帧中别名为列的跨距( struct 的大小).

示例 struct 可能是:

struct {
   int32_t a;
   double b;
   int16_t c;
}

可以使用python生成这样的记录文件,如下所示:

from struct import pack, unpack
db = open("binarydb", "wb")
for i in range(1,1000):
    packed = pack('<idh', i, i*3.14, i*2)
    db.write(packed)
db.close()

然后,问题是如何将这样的文件作为数据帧有效地查看.如果我们假设文件的长度为数亿行,则需要使用mem映射解决方案.

使用memmap,如何将numpy数组(或替代数组 struct )映射到列a的整数序列.在我看来,这需要能够指示int32系列"a"的跨距(14字节)和偏移量(在本例中为0),float64系列"b"的偏移量为4,int16系列"c"的偏移量为12.

我已经看到,如果一个mmap'ed文件包含一个数据类型,那么可以很容易地针对该文件创建一个numpyarray.是否有方法通过指示类型、偏移和跨距来 pull 此文件中的不同系列?使用这种方法,可以将mmapped列呈现给pandas或其他数据帧实现.

更好的是,是否有一种简单的方法可以将自定义mem映射格式集成到Dask中,从而在文件中获得延迟分页的好处?

推荐答案

你可以用numpy.memmap来做这件事.由于输入数据类型不是本机类型,因此需要使用advanced Numpy data types.请注意,您需要提前知道数组的大小,因为Numpy不支持无界流,而是支持固定大小的array.

size = 999

datatype = np.dtype([('a', np.int32), ('b', np.float64), ('c', np.int16)])

# The final memory-mapped array
data = np.memmap("binarydb", dtype=datatype, mode='write', shape=size)

for i in range(1,1+size):
    data[i]['a'] = i
    data[i]['b'] = i*3.14
    data[i]['c'] = i*2

请注意,矢量化操作通常比Numpy中的直接索引快得多.如果操作无法矢量化,还可以使用Numba加速直接索引.

请注意,内存映射区域可以刷新,但在Numpy中尚未关闭.

Python相关问答推荐

我们可以在apps.py?中使用Post_Save信号吗

在Python中是否可以输入使用任意大小参数列表的第一个元素的函数

我可以使用极点优化这个面向cpu的pandas代码吗?

当测试字符串100%包含查询字符串时,为什么t fuzzywuzzy s Process.extractBests不给出100%分数?

如何观察cv2.erode()的中间过程?

是什么导致对Python脚本的jQuery Ajax调用引发500错误?

使用from_pandas将GeDataFrame转换为polars失败,ArrowType错误:未传递numpy. dype对象

如何使用stride_tricks.as_strided逆转NumPy数组

从DataFrame.apply创建DataFrame

Python中MongoDB的BSON时间戳

Chatgpt API不断返回错误:404未能从API获取响应

如何根据日期和时间将状态更新为已过期或活动?

在函数内部使用eval(),将函数的输入作为字符串的一部分

ModuleNotFound错误:没有名为flags.State的模块; flags不是包

如何过滤包含2个指定子字符串的收件箱列名?

如何并行化/加速并行numba代码?

Django—cte给出:QuerySet对象没有属性with_cte''''

在Python 3中,如何让客户端打开一个套接字到服务器,发送一行JSON编码的数据,读回一行JSON编码的数据,然后继续?

dask无groupby(ddf. agg([min,max])?''''

搜索按钮不工作,Python tkinter