【问题标题】:Python - Fastest way to generate list of random colours with fixed alphaPython - 生成具有固定 alpha 的随机颜色列表的最快方法
【发布时间】:2014-02-24 08:21:40
【问题描述】:

因此,我希望在 Python 中生成大约 3.32 亿种颜色(具有 4 个值的元组 - r、g、b、a)的大型列表,但 alpha 值固定为 0.6。我还需要复制其下方行中的每种颜色(即我最终有 6.64 亿行 - 只有 3.32 亿种不同的颜色。

我已经尝试并测试了很多方法,但到目前为止最快的结论是使用 numpy 来:

  1. 使用 numpy random 创建一个长度为 3.32 亿的数组,每行包含 3 个随机浮点值
  2. 使用 numpy tile 创建第二个长度相同的数组,每行的值 [0, 0, 0, 0.6]
  3. 将第一个数组中的值复制到第二个数组每行的前 3 个值中
  4. 使用 numpy repeat 函数将每一行重复到下面新插入的行(将数组与前一行的重复项交错)

此代码大约需要。 574 秒或 10 分钟,是:

import time
import numpy as np

t1 = time.time()

randomnos = np.random.random_sample((332000000, 3)) 
trans = np.tile([0,0,0,0.6],(332000000, 1))
trans[:,:-1] = randomnos
colorarray = np.repeat(trans, 2, axis=0)

t2 = time.time()

totaltime = t2 - t1

print "Time Taken = %f seconds" % totaltime

现在,由于我不需要在运行时生成随机数,我得出结论,我可以只运行此代码一次并保存到文件(使用 numpy save),然后在运行时使用 numpy load 函数读取文件,但是尽管这要快得多,但对我来说仍然太慢了 106 秒或大约 2 分钟。

我认为必须有更快的方法在运行时生成随机颜色?

所需的输出类似于:

array = [[ 0.98112321  0.38567094  0.2430455   0.6       ]
 [ 0.98112321  0.38567094  0.2430455   0.6       ]
 [ 0.54728619  0.97823465  0.86675383  0.6       ]
 [ 0.54728619  0.97823465  0.86675383  0.6       ]
 ..., 
 [ 0.15047076  0.55844066  0.79842858  0.6       ]
 [ 0.15047076  0.55844066  0.79842858  0.6       ]
 [ 0.53637406  0.52150776  0.44890727  0.6       ]
 [ 0.53637406  0.52150776  0.44890727  0.6       ]]

【问题讨论】:

  • 如果你想从文件中读取:试试picklecpickle。或者使用像 sqlite 这样的小型数据库。
  • 感谢您的回答,我尝试过 pickle 和 numpy 加载速度更快(颜色以二进制格式保存),即使是 sql 数据库检索这么多行的速度也很慢,所以我没有认为它会更快,理想情况下,由于额外的开销,我不想将其存储在数据库中。
  • 您的颜色可以容纳多少位 rgb?只有 16,777,216 种 24 位颜色,因此枚举可能会更快。

标签: python performance random numpy colors


【解决方案1】:

我对您显示的代码有点困惑。您似乎在以一种非常迂回的方式做事,我可能误解了您想要什么。

但是,据我了解,您想要:

import numpy as np

colorarray = np.random.random_sample((332000000, 4))
colorarray[:, -1] = 0.6
colorarray = np.vstack([colorarray, colorarray])

这对我来说大约需要 30 秒。

或者,如果您想尽可能地优化事物,您可以节省一两秒:

num = 332000000
colorarray = np.empty((2 * num, 4), dtype=float)
colorarray[:num, :3] = np.random.random_sample((num, 3))
colorarray[:num, -1] = 0.6
colorarray[num:] = colorarray[:num]

这大约需要 28 秒。


编辑:我完全误解了你想要做什么。 (我的错,不是你的。你有一个很好的、独立的、可运行的例子。我只是没有仔细阅读!)

要“交错”这些值,我们可以使用简单的切片技巧。从更优化的示例开始:

num = 332000000
colorarray = np.empty((2 * num, 4), dtype=float)
colorarray[::2, :3] = np.random.random_sample((num, 3))
colorarray[::2, -1] = 0.6
colorarray[1::2] = colorarray[::2]

这需要更长的时间来运行(约 42 秒),但会给出你想要的值。

numpy.repeat,正如您最初使用的那样,实际上比分配给切片要快一些,在这种情况下。因此,我们可以通过以下方式将事情缩短到约 34 秒:

colorarray = np.empty((num, 4), dtype=float)
colorarray[:, :3] = np.random.random_sample((num, 3))
colorarray[:, -1] = 0.6
colorarray = np.repeat(colorarray, 2, axis=0)

编辑 2

最后,我终于想对您的原始代码进行基准测试...它的速度实际上与我的最终版本几乎相同。看来我对你的例子是“环形交叉路口”的评论完全不合时宜!

【讨论】:

  • 感谢您的回复,我为您的优化方案计时,耗时106秒,比从文件中读取要快。但是没有更快的方法吗?
  • 嗯,瓶颈在于生成随机值。如果您对非随机但可能不同的值没问题,您可以使用其他一些选项(例如,使用内存中发生的任何内容初始化数组,然后将其重新缩放到 0-1 范围)。稍后我会添加一些其他示例。
  • 另外,我刚刚检查了优化解决方案的输出,我想我对我想要的输出感到困惑。似乎在您的解决方案中我没有我需要的重复行,我将编辑我的问题以添加所需输出的示例。
  • @JamesElder - 啊!你的代码现在更有意义了!我运行了它,但不知何故错过了输出中的“交错”。是的,还有一种有效的方法可以做到这一点。稍等一下,我将添加一个更新的示例。 (至于机器,是的,它很快,但它可能更多地与内存速度有关,而不是 CPU 速度。)
  • 也只是想说我在交错中重复行 14 次,而不是 2 'colorarray = np.repeat(colorarray, 14, axis=0)' (因为我只是简化为了这个问题,到 2)这就是为什么我说 574 秒。仅在我的代码花费与您所说的 34 秒相似的时间后才复制行。
猜你喜欢
  • 2022-10-04
  • 2012-11-29
  • 2018-05-16
  • 2010-10-26
  • 2023-04-01
  • 2011-02-12
  • 2018-04-02
  • 1970-01-01
  • 2018-07-03
相关资源
最近更新 更多