Python 是否有可能进一步优化这个数字运算算法?

Python 是否有可能进一步优化这个数字运算算法?,python,numpy,scipy,Python,Numpy,Scipy,我试图用Python进行一些数据处理,我有一个嵌套的循环,可以进行一些算术计算。内部循环执行20.000次,因此以下代码需要很长时间: for foo in foo_list: # get bar_list for foo for bar in bar_list: # do calculations w/ foo & bar 使用Numpy或Scipy这个循环会更快吗?使用Numpy: import numpy as np foo = np.array(

我试图用Python进行一些数据处理,我有一个嵌套的循环,可以进行一些算术计算。内部循环执行20.000次,因此以下代码需要很长时间:

for foo in foo_list:
    # get bar_list for foo
    for bar in bar_list:
        # do calculations w/ foo & bar
使用Numpy或Scipy这个循环会更快吗?

使用Numpy:

import numpy as np
foo = np.array(foo_list)[:,None]
bar = np.array(bar_list)[None,:]
然后

或其他操作创建带有相应结果的数组
len(foo)*len(bar)

例如:

>>> foo_list = [10, 20, 30]
>>> bar_list = [4, 5]
>>> foo = np.array(foo_list)[:,None]
>>> bar = np.array(bar_list)[None,:]
>>> 2 * foo + bar

array([[24, 25],
       [44, 45],
       [64, 65]])

我用过numpy进行图像处理。在我使用for(x在行中){y在列中}(或者反之亦然)之前,您就知道了


这对于小图像来说是很好的,但会很高兴地消耗ram。相反,我切换到numpy.array。更快。

取决于循环中实际发生的情况,是的。
numpy允许使用数组和矩阵,这允许索引使代码执行更快,并且在某些情况下可以消除循环

索引示例:

import magic_square as ms

a = ms.magic(5)

print a # a is an array
[[17 24  1  8 15]
 [23  5  7 14 16]
 [ 4  6 13 20 22]
 [10 12 19 21  3]
 [11 18 25  2  9]]

# Indexing example.  
b = a[a[:,1]>10]*10

print b
[[170, 240,  10,  80, 150],
 [100, 120, 190, 210,  30],
 [110, 180, 250,  20,  90]]

在分析一个或多个数组时,应该清楚索引是如何显著提高速度的。这是一个强大的工具…

如果这些是聚合统计,考虑使用。例如,如果要对所有不同的
(foo,bar)
对执行某些操作,则可以按这些项分组,然后应用矢量化NumPy操作:

import pandas, numpy as np
df = pandas.DataFrame(
                      {'foo':[1,2,3,3,5,5], 
                       'bar':['a', 'b', 'b', 'b', 'c', 'c'], 
                       'colA':[1,2,3,4,5,6], 
                       'colB':[7,8,9,10,11,12]})
print df.to_string()

# Computed average of 'colA' weighted by values in 'colB', for each unique
# group of (foo, bar).
weighted_avgs  = df.groupby(['foo', 'bar']).apply(lambda x: (1.0*x['colA']*x['colB']).sum()/x['colB'].sum())

print weighted_avgs.to_string()
这将仅为数据对象打印以下内容:

  bar  colA  colB  foo
0   a     1     7    1
1   b     2     8    2
2   b     3     9    3
3   b     4    10    3
4   c     5    11    5
5   c     6    12    5
这是分组的、聚合的输出

foo  bar
1    a      1.000000
2    b      2.000000
3    b      3.526316
5    c      5.521739

你在做什么计算?这取决于,你必须准确地确定哪个计算花费的时间最长。如果访问foo和bar的时间太长,因为它必须等待将其从硬盘的读写头中拉出,那么优化循环的性质就是将重点放在错误的区域。
foo  bar
1    a      1.000000
2    b      2.000000
3    b      3.526316
5    c      5.521739