如何从list-python的大型列表中创建Numpy数组

时间:2014-03-18 00:32:07

标签: python arrays numpy pandas pytables

我有一个包含1,200行和500,000列的列表。如何将其转换为numpy数组?

我已经阅读Bypass "Array is too big" python error上的解决方案,但他们没有帮助。

我试图将它们放入一个numpy数组中:

import random
import numpy as np
lol = [[random.uniform(0,1) for j in range(500000)] for i in range(1200)]
np.array(lol)

[错误]:

ValueError: array is too big.

然后我尝试了pandas

import random
import pandas as pd
lol = [[random.uniform(0,1) for j in range(500000)] for i in range(1200)]
pd.lib.to_object_array(lol).astype(float)

[错误]:

ValueError: array is too big.

我也试过hdf5,因为@askewchan建议:

import h5py
filearray = h5py.File('project.data','w')
data = filearray.create_dataset('tocluster',(len(data),len(data[0])),dtype='f')
data[...] = data

[错误]:

    data[...] = data
  File "/usr/lib/python2.7/dist-packages/h5py/_hl/dataset.py", line 367, in __setitem__
    val = numpy.asarray(val, order='C')
  File "/usr/local/lib/python2.7/dist-packages/numpy/core/numeric.py", line 460, in asarray
    return array(a, dtype, copy=False, order=order)
  File "/usr/lib/python2.7/dist-packages/h5py/_hl/dataset.py", line 455, in __array__
    arr = numpy.empty(self.shape, dtype=self.dtype if dtype is None else dtype)
ValueError: array is too big.

这篇文章显示我可以在磁盘Python: how to store a numpy multidimensional array in PyTables?中存储一个巨大的numpy数组。但我甚至无法将我的列表列表变成一个numpy数组=(

5 个答案:

答案 0 :(得分:4)

在具有32GB RAM和64位Python的系统上,您的代码为:

import random
import numpy as np
lol = [[random.uniform(0,1) for j in range(500000)] for i in range(1200)]
np.array(lol)

对我来说效果很好,但它可能不是最好的选择。这就是为PyTables而构建的东西。由于您处理同类数据,您可以使用Array类,或者更好的是CArray class(支持压缩)。这可以通过以下方式完成:

import numpy as np
import tables as pt

# Create container
h5 = pt.open_file('myarray.h5', 'w')
filters = pt.Filters(complevel=6, complib='blosc')
carr = h5.create_carray('/', 'carray', atom=pt.Float32Atom(), shape=(1200, 500000), filters=filters)

# Fill the array
m, n = carr.shape
for j in xrange(m):
    carr[j,:] = np.random.randn(n) 

h5.close() # "myarray.h5" (~2.2 GB)

# Open file
h5 = pt.open_file('myarray.h5', 'r')
carr = h5.root.carray
# Display some numbers from array
print carr[973:975, :4]
print carr.dtype    

如果您print carr.flavor,它将返回'numpy'。您可以像使用NumPy数组一样使用此carr。信息存储在磁盘上但速度很快。

答案 1 :(得分:2)

使用h5py / hdf5

import numpy as np
import h5py

lol = np.empty((1200, 5000)).tolist()

f = h5py.File('big.hdf5', 'w')
bd = f.create_dataset('big_dataset', (len(lol), len(lol[0])), dtype='f')
bd[...] = lol

然后,我相信您可以访问您的大数据集bd,就像它是一个数组一样,但是它是从磁盘而不是内存中存储和访问的:

In [14]: bd[0, 1:10]
Out[14]:
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.], dtype=float32)

你可以在一个文件中有多个“数据集”(多个数组)。

abd = f.create_dataset('another_big_dataset', (len(lol), len(lol[0])), dtype='f')
abd[...] = lol
abd += 10

然后:

In [24]: abd[:3, :10]
Out[24]: 
array([[ 10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.],
       [ 10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.],
       [ 10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.,  10.]], dtype=float32)

In [25]: bd[:3, :10]
Out[25]: 
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]], dtype=float32)

我的电脑无法处理您的示例,因此我无法使用您的尺寸阵列进行测试,但我希望它有效!

根据您对阵列的要求,pytables可能会有更多的运气,这比h5py要多得多。

另见:
Python Numpy Very Large Matrices
exporting from/importing to numpy, scipy in SQLite and HDF5 formats

答案 2 :(得分:1)

您是否尝试过分配dtype?这对我有用。

import random
import numpy as np
lol = [[random.uniform(0,1) for j in range(500000)] for i in range(1200)]
ar = np.array(lol, dtype=np.float64)

另一种选择是使用火焰。 http://blaze.pydata.org/

import random
import blaze
lol = [[random.uniform(0,1) for j in range(500000)] for i in range(1200)]
ar = blaze.array(lol)

答案 3 :(得分:0)

问题似乎是你正在使用某种东西(OS或python)只有32位,这是大小限制的来源。解决方案是升级到64位。

答案 4 :(得分:-2)

另一种选择是:

lol = np.empty((1200,500000))
for i in range(lol.shape[0]):
    lol[i] = [random.uniform(0,1) for j in range(lol.shape[1])]

这与您的初始表单相当接近,我希望它可以适合您的代码。我无法测试您的数字,因为我没有足够的RAM来处理数组。