简体   繁体   English

取第一个和第二个中间条目,第二个和第二个中间条目的点积,直到中间1和最后一个条目python / numpy

[英]Take dot product of first and middle entry, second and middle+1 entries until middle-1 and last entry python/numpy

Sorry for the vague sounding question, I really couldn't think of a better way to describe what I am trying to do 对于模糊的声音问题我很抱歉,我真的想不出更好的方式来描述我想要做的事情

I have a 81x990000x3 array and for each of the 81 entries; 我有一个81x990000x3阵列和81个条目中的每一个; I need to sum the dot product of the first entry with the 495000th entry (the middle), the second with the 495001st entry and so on until the 494999th entry with the last entry. 我需要将第一个条目的点积与第495000个条目(中间)相加,第二个条目与495001条目相加,依此类推,直到最后一个条目的494999条目。

Right now I have it being done in a loop like this: 现在我在这样的循环中完成它:

import numpy as np
summed = 0

Nt = 990000
i = Nt/2

for k in xrange(81):
  for j in xrange(Nt-i-1):
    vec1 = array[k][j]
    vec2 = array[k][j+i]

    summed += np.dot(vec1,vec2)

This is obviously quite slow, however, since it is going through 81x990000 = 80190000 entries. 然而,这显然是非常缓慢的,因为它经历了81x990000 = 80190000个条目。

Is there a more numpythonic way to do this? 是否有更多的numpythonic方式来做到这一点?

NB reading your question, I think you want your second nested loop to be for j in xrange(Nt-i): since xrange excludes the upper limit. NB读你的问题,我想你希望你的第二个嵌套循环是for j in xrange(Nt-i):因为xrange排除了上限。

I think you can what you want with einsum : 我想你可以用einsum你想要的einsum

import numpy as np
summed = 0

dim1 = 2  # this is 81 in your case
dim2 = 4  # this is 990000 in your case
array = np.random.random(size=(dim1, dim2, 3))

Nt = dim2
i = Nt // 2

for k in xrange(dim1):
    summed = 0
    for j in xrange(dim2-i):
        vec1 = array[k][j]
        vec2 = array[k][j+i]
        summed += np.dot(vec1,vec2)
    print summed

print '='*70

for k in xrange(dim1):
    summed = np.einsum('ij,ij', array[k][:Nt//2], array[k][Nt//2:])
    print summed

eg 例如

2.0480375425
1.89065215839
======================================================================
2.0480375425
1.89065215839

Doubtless you can even remove the outer loop as well (though in your case it probably won't speed things up much): 毫无疑问,你甚至可以删除外部循环(虽然在你的情况下,它可能不会加快速度):

np.einsum('kij,kij->k', array[:,:Nt//2,:], array[:,Nt//2:,:])

gives

[ 2.0480375425  1.89065215839]

Since you want to go from 0 until the 494999th entry, I think the code needs a slight edit for the jth iterations and has to be for j in xrange(Nt-i) instead. 由于你想要从0494999th条目,我认为代码需要对jth次迭代进行轻微编辑,而必须for j in xrange(Nt-i) Now, back to the problem at hand, you are basically cutting each 3D slice into two halves and doing elementwise multiplication between them and thereafter summing all elements. 现在,回到手头的问题,你基本上将每个3D slice成两半,然后在它们之间进行元素乘法,然后对所有元素求和。 Here, by slice I mean a 2D array formed by axis =(1,2) . 这里,切片I是指由axis =(1,2)形成的2D阵列。

To solve our case, you can simulate - 要解决我们的情况,你可以模拟 -

  • Cutting into two halves with : .reshape() . 切入两半: .reshape()
  • Elementwise multiplication betwen correspondng elements with : .prod() . 元素乘法在相应的元素之间: .prod()
  • Summing all elements with : .sum() . 用以下内容对所有元素求和: .sum()

Thus, the implementation would look something like this - 因此,实现看起来像这样 -

m,n,r = array.shape
out = array.reshape(m,2,-1,r).prod(1).sum()

Runtime tests and verify output - 运行时测试并验证输出 -

Define functions : 定义功能:

def vectorized_app(array):
    m,n,r = array.shape
    return array.reshape(m,2,-1,r).prod(1).sum()

def org_app(array):
    m,n,r = array.shape
    Nt = n
    i = Nt/2
    summed = 0
    for k in xrange(m):
      for j in xrange(Nt-i):
        vec1 = array[k][j]
        vec2 = array[k][j+i]
        summed += np.dot(vec1,vec2)
    return summed

Runtimes : 运行时:

In [94]: array = np.random.rand(81,9900,3)

In [95]: org_app(array)
Out[95]: 300450.24128635536

In [96]: vectorized_app(array)
Out[96]: 300450.24128635362

In [97]: %timeit org_app(array)
1 loops, best of 3: 1.29 s per loop

In [98]: %timeit vectorized_app(array)
100 loops, best of 3: 16.1 ms per loop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python拆分第一个“中间”和最后一个词 - Python Split first "middle" and last word 当不是每个人都有中间名时,将名字解析为名字、中间名、姓氏 - Parse names into first, middle, last when not everyone has a middle name 使用 Python 将名字拆分为名字、中间名和姓氏 - Splitting a name into first, middle and last name using Python 索引numpy数组的中间? - Index the middle of a numpy array? 第二行中间的第三个子图居中 python - Center the third subplot in the middle of second row python Python:将全名“ First Last”,“ First Middle Last”等拆分为单独的变量? - Python: split a full name “First Last”, “First Middle Last,” etc … into separate variables? 在 python 的名称列表中查找首字母和中间首字母 - Finding and first and middle initials in a list of names in python 你的function partition_median()没有使用第一个中间元素和最后一个元素的中值,只取中间元素 - Your function partition_median () does not use the median of the first middle and last element, but only takes the middle element python函数返回第一个非零带状中间零并返回数字字符串的最后一部分 - python function return first non zero strip middle zeros and return last part of number string 熊猫将名称列拆分为姓氏和名字忽略中间名python - Pandas split name column into last and first name ignore middle name python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM