有没有办法查看python的array.array()?

2 投票
2 回答
1150 浏览
提问于 2025-04-16 15:49

我正在生成很多比较大的“随机”文件(大约500MB),这些文件的内容是通过多次调用random.randint(...)得到的。我想先分配一个大的缓冲区,把长整型数据写入这个缓冲区,然后定期把这个缓冲区的数据刷新到磁盘上。目前我使用的是array.array(),但我找不到一种方法可以创建这个缓冲区的视图。我需要这样做,是为了把缓冲区中有效的数据部分传递给hashlib.update(...),并将有效的缓冲区部分写入文件。我可以使用切片操作符,但据我所知,这样会创建缓冲区的一个副本,而这正是我不想要的。

有没有我没有想到的方法呢?

更新:

我按照用户42005和hgomersall的建议使用了numpy。不幸的是,这并没有给我带来我想要的速度提升。我的一个非常简单的C程序在11秒内生成了大约700MB的数据,而我用numpy写的Python程序却需要大约700秒!很难相信这两者之间的性能差距会这么大(我更倾向于相信我在某个地方犯了一个简单的错误...)

2 个回答

5

我想你可以试试numpy这个库:http://www.numpy.org。在numpy中,基本的数组类型至少支持不复制的视图,也就是说你可以在不复制数据的情况下查看和操作数组。

4

Numpy在处理数组时非常灵活和强大,特别是在尽量减少复制的情况下。举个例子:

import numpy
a = numpy.random.randint(0, 10, size=10)
b = numpy.a[3:10]

这里的b是原始数组的一个视图,也就是说它是对原数组的一种引用。

Numpy数组可以直接访问数据,使用起来也很方便,可以轻松改变数据类型。比如:

a = numpy.random.randint(0, 10, size=10)
b = numpy.frombuffer(a.data, dtype='int8')

这里的b现在是内存中的一个视图,所有数据都变成了8位整数(数据本身没有改变,所以每个64位整数现在变成了8个8位整数)。这些缓冲区对象(来自a.data)是标准的Python缓冲区对象,因此可以在所有需要使用缓冲区的地方使用。

对于多维数组也是一样的。不过,你需要注意数据在内存中的排列方式。比如:

a = numpy.random.randint(0, 10, size=(10, 10))
b = numpy.frombuffer(a[3,:].data, dtype='int8')

这个是可以工作的,但

b = numpy.frombuffer(a[:,3].data, dtype='int8')

会返回一个错误,提示无法获取不连续数组的单段缓冲区。这个问题不太明显,因为简单地将那个视图分配给一个变量,使用

b  = a[:,3]

会返回一个完全合适的numpy数组。然而,它在内存中并不是连续的,因为它是对另一个数组的视图,而那个数组不一定是(在这个例子中也不是)连续内存的视图。你可以通过数组的flags属性获取关于数组的信息:

a[:,3].flags

这会返回(除了其他信息)C_CONTIGUOUS(C语言顺序,行优先)和F_CONTIGUOUS(Fortran顺序,列优先)都为False,但

a[3,:].flags

返回它们都为True(在二维数组中,最多只能有一个为True)。

撰写回答