我想从一个非常庞大的列表中创建一个scipy数组。但不幸的是我遇到了一个问题。
我有一个字符串列表 xs 。每个字符串的长度为 1 。
>>> type(xs)
<type 'list'>
>>> len(xs)
4001844816
如果我只转换第一个 10 元素,那么一切仍然按预期工作。
>>> s = xs[0:10]
>>> x = scipy.array(s)
>>> x
array(['A', 'B', 'C', 'D', 'E', 'F', 'O', 'O'],
dtype='|S1‘)
>>> len(x)
10
对于整个列表,我得到了这个结果:
>>> ary = scipy.array(xs)
>>> ary.size
1
>>> ary.shape
()
>>> ary[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: 0-d arrays can't be indexed
>>>ary[()]
...The long list
解决方法是:
test = scipy.zeros(len(xs), dtype=(str, 1))
for i in xrange(len(xs)):
test[i] = xs[i]
这不是内存不足的问题。 到目前为止,我将使用解决方法(需要15分钟)。但我想了解这个问题。
谢谢
-
编辑:
备注解决方法test[:] = xs
不起作用。 (同样失败, 0-d IndexError)
在我的macbook上 2147483648 是造成问题的最小尺寸。 我用这个小脚本确定了它:
#!/usr/bin/python
import scipy as sp
startlen = 2147844816
xs = ["A"] * startlen
ary = sp.array(xs)
while ary.shape == ():
print "bad", len(xs)
xs.pop()
ary = sp.array(xs)
print "good", len(xs)
print ary.shape, ary[0:10]
print "DONE."
这是输出
...
bad 2147483649
bad 2147483648
good 2147483647
(2147483647,) ['A' 'A' 'A' 'A' 'A' 'A' 'A' 'A' 'A' 'A']
DONE.
python版本是
>>> sys.version
'2.7.5 (default, Aug 25 2013, 00:04:04) \n[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)]'
>>> scipy.version.version
'0.11.0'
答案 0 :(得分:1)
假设您有64位OS / Python / Numpy,您可能会遇到一些内存不足的情况 - 有时可能会出现异常情况。你的第一个列表是4GB然后你为numpy数组额外分配了4GB。即使对于x64,这些都是大阵列。你以前见过memmap数组吗?
我在下面创建了一系列memmap数组,显示了(对于我的机器)断点的位置(主要是磁盘IO)。但是,适当的阵列大小可以创建30亿'S1'元素。此代码可能会帮助您查看memmap数组是否可以为您的问题提供一些好处。它们易于使用。您的15分钟解决方法可以使用memmap数据加速。
baseNumber = 3000000L
#dataType = 'float64'#
numBytes = 1
dataType = 'S1'
for powers in arange(1,7):
l1 = baseNumber*10**powers
print('working with %d elements'%(l1))
print('number bytes required %f GB'%(l1*numBytes/1e9))
try:
fp = numpy.memmap('testa.map',dtype=dataType, mode='w+',shape=(1,l1))
#works
print('works')
del fp
except Exception as e:
print(repr(e))
"""
working with 30000000 elements
number bytes required 0.030000 GB
works
working with 300000000 elements
number bytes required 0.300000 GB
works
working with 3000000000 elements
number bytes required 3.000000 GB
works
working with 30000000000 elements
number bytes required 30.000000 GB
works
working with 300000000000 elements
number bytes required 300.000000 GB
IOError(28, 'No space left on device')
working with 3000000000000 elements
number bytes required 3000.000000 GB
IOError(28, 'No space left on device')
"""