【问题标题】:Fill up a 2D array while iterating through it在迭代时填充二维数组
【发布时间】:2015-05-20 23:28:51
【问题描述】:

我想做的一个例子是,而不是如下所示:

Z_old = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
for each_axes in range(len(Z_old)):
    for each_point in range(len(Z_old[each_axes])):
        Z_old[len(Z_old)-1-each_axes][each_point] = arbitrary_function(each_point, each_axes)

我现在不想用零初始化 Z_old 数组,而是在迭代它时用值填充它,这将类似于下面写的,尽管它的语法非常错误,但这就是我想要达到的结束。

 Z = np.zeros((len(x_list), len(y_list))) for Z[len(x_list) -1 - counter_1][counter_2] is equal to power_at_each_point(counter_1, counter_2] for counter_1 in range(len(x_list)) and counter_2 in range(len(y_list))]

【问题讨论】:

  • 你仍然专注于错误的事情。用 0 初始化数组几乎没有时间,所以不值得担心。问题在于内部循环,您在其中调用非常慢的arbitrary_function X*Y 次。这就是你所有时间都花在这上面的地方,所以这就是你需要优化的部分。
  • 第一个表达式很好(使用[x,y] 索引)。第二个是对列表理解的错误模仿。
  • 将来,如果您在创建与另一个问题相关的问题时包含指向它的链接,例如this,这将非常有帮助。有很多与这个问题相关的背景信息,除非他们碰巧记得那个问题,或者经历了与您上次经历的所有相同的 cmets 和编辑,否则没人会知道。
  • @abarnert 好的,下次我一定会包括在内,对不起。

标签: python numpy matrix multidimensional-array


【解决方案1】:

正如我在对your previous question 的回答中所解释的,您确实需要对arbitrary_function 进行矢量化处理。

可以通过在函数上调用np.vectorize 来做到这一点,如下所示:

Z = np.vectorize(arbitrary_function)(np.arange(3), np.arange(5).reshape(5, 1))

但这只会给你一点加速。在您的情况下,由于 arbitrary_function 正在做大量工作(包括打开和解析 Excel 电子表格),因此不太可能产生足够的差异,甚至无法注意到,更不用说解决您的性能问题了。

使用 NumPy 进行加速的全部意义在于找到一次对一个值进行操作的代码的慢速部分,并将其替换为对整个数组(或至少一整行或一列)进行操作的代码立刻。您不能通过查看非常外部的循环来做到这一点,您需要查看非常 inside 循环。换句话说,arbitrary_function

在您的情况下,您可能想要做的是将 Excel 电子表格读入一个全局数组,其结构方式使得您的流程中的每个步骤都可以写为对该数组的数组范围的操作。这是否意味着乘以数组的一部分,使用输入值作为索引来索引数组,或者完全不同的东西,它必须是 NumPy 可以在 C 中为你做的事情,或者 NumPy 不会帮助你。


如果您不知道如何做到这一点,您可能需要考虑不使用 NumPy,而是使用 Cython 编译您的内部循环,或者在 PyPy 下运行您的代码。您仍然几乎可以肯定需要将“打开并解析整个 Excel 电子表格”移到内部循环之外,但至少您不必弄清楚如何根据矢量化操作重新考虑您的问题,因此它可能对你来说更容易。

【讨论】:

  • 老兄需要意识到你一次用太多信息打我,我对 python 不太熟悉,这就是我面临这些性能问题的原因。我会尝试再读 10 遍您所说的内容,并了解我应该做些什么来解决我的性能问题,我非常感谢您的帮助。我可以说的一件事是我已经将 excel 工作表信息提取到 python 中的列表列表中,但我绝对可以尝试将其更改为 np 数组并改为使用它。
  • @MahmoudAyman:抱歉,但如果你真的想学习如何使用 NumPy 高效编程,还有很多东西要学,你必须从基础开始。我写不出一个答案,可以为您提供完整的教程,从向量化的含义一直到向量化不同类型问题的技巧和窍门;没有任何东西可以替代您努力学习它。
  • @MahmoudAyman:同时,您还需要学习更广泛的优化主题:如何分析您的代码以找出哪些部分很慢,以及如何尝试猜测哪些部分很重要您知道要分析什么,如何了解哪些优化会影响哪些部分,等等。
  • 我渴望永远学习,现在我正试图应用你所说的。只是我一直在使用 python 并没有太多了解很多东西,当然还有很多东西要学。我将从 excel 工作表中提取的数据作为 np 数组开始工作并使用它。
  • 公平地说,对 python 函数进行矢量化在很大程度上是一种方便,它不会提供超过循环的加速。 (事实上​​我很确定 numpy 库用简单的循环结构来实现它)(这说明我是 +1 仍然是个好主意)
【解决方案2】:
rows = 10
cols = 10
Z = numpy.array([ arbitrary_function(each_point, each_axes) for each_axes in range(cols) for each_point in range(rows) ]).reshape((rows,cols))

也许?

【讨论】:

  • 但是我想使用 Numpy 数组是不是可能?
  • 这不会有太大帮助;您只是将嵌套的 for 语句转换为嵌套的理解。你可以通过使用np.vectorize 将其转换为 NumPy 嵌套循环来做得更好。但是,正如我在回答中解释的那样,我很确定我们谈论的可能是 15% 的加速(你的版本)或 20% 的加速(我的),这部分代码占总数不到 0.1%时间,所以无关紧要。
猜你喜欢
  • 2021-05-10
  • 2016-05-27
  • 1970-01-01
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
相关资源
最近更新 更多