我一直在尝试实施一些修改来加速这个伪代码:
>>> A=np.array([1,1,1,2,2,2,3,3,3])
>>> B=np.array([np.power(A,n) for n in [3,4,5]])
>>> B
array([[ 1, 1, 1, 8, 8, 8, 27, 27, 27],
[ 1, 1, 1, 16, 16, 16, 81, 81, 81],
[ 1, 1, 1, 32, 32, 32, 243, 243, 243]])
A的元素经常重复10-20次,B的形状需要保留,因为它后面再乘以另一个相同形状的数组。
我的第一个想法是使用以下代码:
uA=np.unique(A)
uB=np.array([np.power(uA,n) for n in [3,4,5]])
B=[]
for num in range(uB.shape[0]):
Temp=np.copy(A)
for k,v in zip(uA,uB[num]): Temp[A==k] = v
B.append(Temp)
B=np.array(B)
### Also any better way to create the numpy array B?
这看起来相当糟糕,而且可能有更好的方法。任何关于如何提高速度的想法都会非常感激。
感谢您的时间。
这是一个更新。我意识到我的功能编码很差。感谢大家的建议。我会在将来更好地重新解释我的问题,以便他们展示所需的一切。
Normal='''
import numpy as np
import scipy
def func(value,n):
if n==0: return 1
else: return np.power(value,n)/scipy.factorial(n,exact=0)+func(value,n-1)
A=np.random.randint(10,size=250)
A=np.unique(A)
B=np.array([func(A,n) for n in [6,8,10]])
'''
Me='''
import numpy as np
import scipy
def func(value,n):
if n==0: return 1
else: return np.power(value,n)/scipy.factorial(n,exact=0)+func(value,n-1)
A=np.random.randint(10,size=250)
uA=np.unique(A)
uB=np.array([func(A,n) for n in [6,8,10]])
B=[]
for num in range(uB.shape[0]):
Temp=np.copy(A)
for k,v in zip(uA,uB[num]): Temp[A==k] = v
B.append(Temp)
B=np.array(B)
'''
Alex='''
import numpy as np
import scipy
A=np.random.randint(10,size=250)
power=np.arange(11)
fact=scipy.factorial(np.arange(11),exact=0).reshape(-1,1)
power=np.power(A,np.arange(11).reshape(-1,1))
value=power/fact
six=np.sum(value[:6],axis=0)
eight=six+np.sum(value[6:8],axis=0)
ten=eight+np.sum(value[8:],axis=0)
B=np.vstack((six,eight,ten))
'''
Alex='''
import numpy as np
import scipy
A=np.random.randint(10,size=250)
power=np.arange(11)
fact=scipy.factorial(np.arange(11),exact=0).reshape(-1,1)
power=np.power(A,np.arange(11).reshape(-1,1))
value=power/fact
six=np.sum(value[:6],axis=0)
eight=six+np.sum(value[6:8],axis=0)
ten=eight+np.sum(value[8:],axis=0)
B=np.vstack((six,eight,ten))
'''
Alex2='''
import numpy as np
import scipy
def find_count(the_list):
count = list(the_list).count
result = [count(item) for item in set(the_list)]
return result
A=np.random.randint(10,size=250)
A_unique=np.unique(A)
A_counts = np.array(find_count(A_unique))
fact=scipy.factorial(np.arange(11),exact=0).reshape(-1,1)
power=np.power(A_unique,np.arange(11).reshape(-1,1))
value=power/fact
six=np.sum(value[:6],axis=0)
eight=six+np.sum(value[6:8],axis=0)
ten=eight+np.sum(value[8:],axis=0)
B_nodup=np.vstack((six,eight,ten))
B_list = [ np.transpose( np.tile( B_nodup[:,i], (A_counts[i], 1) ) ) for i in range(A_unique.shape[0]) ]
B = np.hstack( B_list )
'''
print timeit.timeit(Normal, number=10000)
print timeit.timeit(Me, number=10000)
print timeit.timeit(Alex, number=10000)
print timeit.timeit(Alex2, number=10000)
Normal: 10.7544178963
Me: 23.2039361
Alex: 4.85648703575
Alex2: 4.18024992943
答案 0 :(得分:4)
如果您将其形状更改为列向量的形状,则可以在np.power
之间广播A
。
>>> np.power(A.reshape(-1,1), [3,4,5]).T
array([[ 1, 1, 1, 8, 8, 8, 27, 27, 27],
[ 1, 1, 1, 16, 16, 16, 81, 81, 81],
[ 1, 1, 1, 32, 32, 32, 243, 243, 243]])
答案 1 :(得分:1)
使用numpy.tile()和numpy.hstack()的组合,如下所示:
A = np.array([1,2,3])
A_counts = np.array([3,3,3])
A_powers = np.array([[3],[4],[5]])
B_nodup = np.power(A, A_powers)
B_list = [ np.transpose( np.tile( B_nodup[:,i], (A_counts[i], 1) ) ) for i in range(A.shape[0]) ]
B = np.hstack( B_list )
转置和堆叠可能会颠倒,这可能会更快:
B_list = [ np.tile( B_nodup[:,i], (A_counts[i], 1) ) for i in range(A.shape[0]) ]
B = np.transpose( np.vstack( B_list ) )
如果您计算的函数非常昂贵,或者重复多次,多次(超过10次),这可能只值得做;做一个瓷砖和堆栈,以防止额外10次计算功率函数可能是不值得的。请基准测试并告诉我们。
编辑:或者,您可以使用广播来摆脱列表理解:
>>> A=np.array([1,1,1,2,2,2,3,3,3])
>>> B = np.power(A,[[3],[4],[5]])
>>> B
array([[ 1, 1, 1, 8, 8, 8, 27, 27, 27],
[ 1, 1, 1, 16, 16, 16, 81, 81, 81],
[ 1, 1, 1, 32, 32, 32, 243, 243, 243]])
这可能非常快,但实际上并没有按照你的要求行事。
答案 2 :(得分:0)
我用200k迭代进行,第一种方法是我的。
import numpy as np
import time
N = 200000
start = time.time()
for j in range(N):
x = np.array([1,1,1,2,2,2,3,3,3])
powers = np.array([3,4,5])
result = np.zeros((powers.size,x.size)).astype(np.int32)
for i in range(powers.size):
result[i,:] = x**powers[i]
print time.time()-start, "seconds"
start = time.time()
for j in range(N):
A=np.array([1,1,1,2,2,2,3,3,3])
B = np.power(A,[[3],[4],[5]])
print time.time()-start, "seconds"
start = time.time()
for j in range(N):
np.power(A.reshape(-1,1), [3,4,5]).T
print time.time()-start, "seconds"
start = time.time()
for j in range(N):
A=np.array([1,1,1,2,2,2,3,3,3])
B=np.array([np.power(x,n) for n in [3,4,5]])
print time.time()-start, "seconds"
可生产
8.88000011444 seconds
9.25099992752 seconds
3.95399999619 seconds
7.43799996376 seconds
larsmans方法显然最快。
(ps如何在没有显式网址的情况下链接到答案或用户@larsman不起作用)