Это, кажется, немного лучше:
import numpy
a = numpy.random.ranf(size=(5,6))
normalized_a = a/numpy.nansum(a)
def original(a, normalized_a):
row_values = []
col_values = []
for row, col in numpy.ndindex(normalized_a.shape):
weight = int(normalized_a[row, col] * 100)
row_values.extend([row] * weight)
col_values.extend([col] * weight)
return sum(row_values)/float(len(row_values)), sum(col_values)/float(len(col_values))
def new(a, normalized_a):
weights = numpy.floor(normalized_a * 100)
nx, ny = a.shape
rows, columns = numpy.mgrid[:nx, :ny]
row_values = numpy.sum(rows * weights)/numpy.sum(weights)
col_values = numpy.sum(columns * weights)/numpy.sum(weights)
return row_values, col_values
def new2(a, normalized_a):
weights = numpy.floor(normalized_a * 100)
nx, ny = a.shape
rows, columns = numpy.ogrid[:nx, :ny]
row_values = numpy.sum(rows * weights)/numpy.sum(weights)
col_values = numpy.sum(columns * weights)/numpy.sum(weights)
return row_values, col_values
print original(a, normalized_a)
print new(a, normalized_a)
print new2(a, normalized_a)
print "timing!!!"
import timeit
print timeit.timeit('original(a, normalized_a)', 'from __main__ import original, a, normalized_a', number=10000)
print timeit.timeit('new(a, normalized_a)', 'from __main__ import new, a, normalized_a', number=10000)
print timeit.timeit('new2(a, normalized_a)', 'from __main__ import new2, a, normalized_a', number=10000)
Результатов на моем компьютере:
(1.8928571428571428, 2.630952380952381)
(1.8928571428571428, 2.6309523809523809)
(1.8928571428571428, 2.6309523809523809)
timing!!!
1.05751299858
0.64871096611
0.497050046921
я использовал некоторые трюки индекса Numpy для векторизации вычисления. Я на самом деле немного удивлен, что мы не сделали лучше. np.ogrid
примерно в два раза быстрее, чем оригинал на тестовой матрице. np.mgrid
находится где-то посередине.
Молодцы. +1 от меня. Хотя, я должен сказать, я немного разочарован. Я думал, что мой ответ был довольно хорош, пока я не увидел этот ... – mgilson
Кажется, этот вопрос только приносит горе тоже респондентам, потому что я тоже не очень доволен: «Дорогой Санта, я был очень хорошим мальчиком в этом году, пожалуйста, принесите мне такой ПК, как @ mgilson's, который работает в два раза быстрее, чем у меня ... »;-) – Jaime
Mine - это Linux-машина, любезно предоставленная моим работодателем :) – mgilson