【问题标题】:Append large lists in python2.7在 python2.7 中追加大列表
【发布时间】:2012-01-27 17:15:14
【问题描述】:

我正在使用 matplotlib 在 x 轴上绘制带有点 ([0,0,0],[0,0,1],[0,0,2],...[255,255,255]) 的图形为此我正在使用列表:

from mpl_toolkits.mplot3d import Axes3D
x=[]
for i,j,k in product(xrange(256), repeat=3):
    x.append([i,j,k])
y=[]
for count in x:
   y.append(probability[count]) # this is how my probability array is stored

pylab.figure(0)
pylab.plot(x,y,'b')
pylab.show()

这个想法是我从之前的帖子中借来的。我是python新手,所以请帮忙。问题是上面的代码给出了“内存错误”。有人可以提供一种将元素附加到“x”的有效方法

【问题讨论】:

  • 问题是上面的代码给出了内存错误。那么,有人可以建议一种将元素附加到 x 的有效方法或其他一些有效的绘图方式
  • 您正在创建大约 256^3 * 4 字节的对象,更不用说在 append() 中创建的每个列表的开销了。仅将 Python 用于仅占用 如此 大量内存的事情才实用。 为什么你这样做有什么具体原因吗?有没有比遍历所有 1600 万个值更有效的方法?
  • 原因是,我必须在图表上绘制这么多点
  • 请注意,您可能不需要在图表上绘制那么多点。你需要绘制足够多的图来捕捉数据的重要特征,包括不太重要区域的波动,我非常非常怀疑你需要 17M 数据点来实现这一点。如果您坚持这样做,那很好,但是 matplotlib 可能不适合您。我预计,在此之前你会开始遇到 Agg 渲染限制。

标签: python numpy scipy matplotlib


【解决方案1】:

首先,我不认为 pylab.plot 做你认为它做的事,你想在 3d 中显示一个表面吗?

其次,你真的应该使用 ndarrays 而不是列表来处理这么大的事情。我相信 matplotlib 无论如何都会将您的列表转换为 ndarrays,因此您最好从数组开始。我认为您想要的是以下内容。

x, y, z = np.mgrid[0:256, 0:256, 0:256]

最后,y 是什么,probability 是什么?我问是因为probability[x[count]] 对我来说看起来很可疑,我想也许你的意思是probability[count] 但即便如此,如果probability 是一个列表,那应该不起作用,如果它是一个数组,它会爆炸并且可能导致你的记忆错误。 (不留痕迹无法确定)。

看看Matplotlib Gallery,他们的示例带有代码,对让事情顺利进行非常有帮助。

【讨论】:

  • 是的,你纠正了它的概率[计数],我已经在我的帖子中纠正了..谢谢。另外,我必须在我的数组上绘制这些点......虽然现在我已经减少了点......但它仍然给我错误
  • 请告诉我们您要做什么。我怀疑如果您尝试仅绘制数据的 (5,5,5) 部分,您会发现您的代码没有按照您认为的那样做。我也不认为probability[count] 是正确的,就像我在回答中所说的那样,如果probability 是一个列表,它将不起作用,如果probability 是一个数组,它就会爆炸。
【解决方案2】:

使用您当前的方法,x 将包含 16777216 (2563) 个元素。您确定需要在图表上绘制这么多点吗?如果没有,请考虑对其进行一些采样,例如,您可以通过简单地将 xrange(256) 替换为 xrange(0, 256, 16) 将其减少到 4096 个样本。

如果 matplotlib 可以绘制 iterables 而不是列表,您可以通过这样做而不是创建列表来节省内存,它可能看起来像这样:

from itertools import product, imap

def get_probability(count):
    return probability[x[count]]   # this code is broken, but from your example

x = product(xrange(256), repeat=3)
y = imap(get_probability, product(xrange(256), repeat=3))
pylab.plot(x, y, 'b')

正如我在上面的评论中指出的,x[count] 将在您的示例中的以下代码中失败:

for count in x:
    y.append(probability[x[count]])

这是因为x 是一个列表列表,所以count 将始终是一个类似于[0, 0, 0] 的列表,所以在循环的第一步中,您将尝试x[[0, 0, 0]] 并获得TypeError: list indices must be integers, not list

【讨论】:

  • 既然get_probability是一个函数,那么这里给count参数传递的是什么值???我是python新手,所以请解释一下..这听起来可能是一个幼稚的问题,但请解释一下。非常感谢您的帮助
  • @user1172532,count 是来自x 的元素。在 Python shell 中尝试:for x in ['a','b','c']: print(x)。 python 中的for 更像是您可能熟悉的其他语言中的foreach
  • @user1172532 - 查看imap 的文档。 get_probability 将为product 生成的每个元素调用。
  • 我尝试了上述方法,但它给了我“TypeError:float() 参数必须是字符串或数字”错误...你能帮我弄清楚吗
  • @user1172532 - 您需要发布更多代码,这里没有任何可能导致该错误的float() 调用。
【解决方案3】:

x 必须是列表列表吗?可以是元组列表吗?

如果可以的话,你可以把它简化成这样:

x = list(product(xrange(256), repeat=3))

【讨论】:

  • 这仍然是 2**24 个元素,在我的机器上每秒占用 1.5GB。
  • 一个 numpy ndarray (np.empty((256,256,256), dtype=int)) 是更好的数据结构。
猜你喜欢
  • 2014-05-09
  • 1970-01-01
  • 2020-09-24
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 2015-06-12
  • 2018-11-16
相关资源
最近更新 更多