numpy学习记录:如何有效地使用numpy处理大规模数据?

原博地址: http://chrisschell.de/2018/02/01/how-to-efficiently-deal-with-huge-Numpy-arrays.html

1. 更快faster: 使用预分配的arrays

假设您从数据库中检索了大量不同的值。您想以某种方式处理这些数据,然后将它们保存到numpy数组中。

不要

不要遍历每个数据并将其逐个添加到数组中,如下所示:

entries = range(1000000) # 1 billion entries
results = np.array((0,)) # empty array
for entry in entries:
    processed_entry = entry + 5 # do something
    results = np.append(results, [processed_entry])

这个例子在我的MacBook Air上大约需要11秒。我使用这样一个循环来填充多维数组,最终有超过10亿条数据。以这种方式构建该数组需要大约45分钟。这里的问题是,python需要一次又一次地为在内存中分配空间以此来对数组进行append操作,这非常耗时。

使用np.zeros方法预分配数组

entries = range(1000000) # 1 million entries
results = np.zeros((len(entries),)) # prefilled array
for idx, entry in enumerate(entries):
    processed_entry = entry + 5 # do something
    results[idx] = processed_entry

这可以在1秒内完成,因为数组已经以完整的大小存在内存中。
如果您事先不知道最终的数组大小,您甚至可以这样做np.resize来调整大小,这仍然比其他方法快得多。

2. 更大larger:使用h5py

有时,你的数组十分大,主存(RAM)不再适应

不要

不要向下面的方式来操作数据

results = np.ones((1000,1000,1000,5))
#do something...
results[100, 25, 1, 4] = 42

执行上述代码,你的RAM将没有空余,不要期望你的电脑还可以做别的,这段代码就占用了将近40GB的内存

显然这是要避免的。我们需要以某种方式将这些数据存储在我们的磁盘上,而不是RAM中。所以需要使用h5py模块:

import h5py

hdf5_store = h5py.File("./cache.hdf5", "a")
results = hdf5_store.create_dataset("results", (1000,1000,1000,5), compression="gzip")

#do something...
results[100, 25, 1, 4] = 42

这将创建一个包含数据的cache.hdf5文件。create_dataset给我们一个对象,我们可以像一个numpy数组一样对待(至少在大多数时候)。另外,我们得到一个包含这个数组的文件,我们可以从其它地方访问它:

hdf5_store = h5py.File("./cache.hdf5", "r")

print(hdf5_store["results"][100, 25, 1, 4]) # 42.0

3.更聪明smarter:不要经常访问数组

不要

这个情况应该是显而易见的,但代码中有时仍然会出现,如果在循环中需要访问数组中的某一值

some_array = np.ones((100, 200, 300))

for _ in range(10000000):
  some_array[50, 12, 199] # get some value some_array

尽管numpy在通过索引访问大型数组时确实很快,但它仍然需要一些时间,在大循环中时间消耗变得非常大。

只需将数组访问移动到循环外部,您就可以获得显着的改进:

some_array = np.ones((100, 200, 300))

the_value_I_need = some_array[50, 12, 199] # access some_array

for _ in range(10000000):
  the_value_I_need

它的运行速度在MacBook Air上其他版本的两倍。大多数时候,像这样的简单事情会减慢一切!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值