Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 列表中成对乘积的总和_Python_Numpy_Pandas_Itertools - Fatal编程技术网

Python 列表中成对乘积的总和

Python 列表中成对乘积的总和,python,numpy,pandas,itertools,Python,Numpy,Pandas,Itertools,这就是我的问题。给你一张单子 xList = [9, 13, 10, 5, 3] 我想计算每个元素乘以后续元素的总和 sum([9*13, 9*10, 9*5 , 9*3]) + sum([13*10, 13*5, 13*3]) + sum([10*5, 10*3]) + sum ([5*3]) 在这种情况下,答案是608 有没有一种方法可以通过itertools或通过numpy实现这一点 下面是我提出的一个函数。它做的工作,但它远远不是理想的,因为我想补充其他东西以及 def

这就是我的问题。给你一张单子

xList = [9, 13, 10, 5, 3]
我想计算每个元素乘以后续元素的总和

sum([9*13, 9*10, 9*5 , 9*3]) + 
sum([13*10, 13*5, 13*3]) + 
sum([10*5, 10*3]) + 
sum ([5*3])
在这种情况下,答案是608

有没有一种方法可以通过
itertools
或通过
numpy
实现这一点

下面是我提出的一个函数。它做的工作,但它远远不是理想的,因为我想补充其他东西以及

    def SumProduct(xList):
        ''' compute the sum of the product 
        of a list 
        e.g. 
        xList = [9, 13, 10, 5, 3]
        the result will be 
        sum([9*13, 9*10, 9*5 , 9*3]) + 
        sum([13*10, 13*5, 13*3]) + 
        sum([10*5, 10*3]) + 
        sum ([5*3])
        '''
        xSum = 0
        for xnr, x in enumerate(xList):
            #print xnr, x
            xList_1 = np.array(xList[xnr+1:])
            #print x * xList_1
            xSum = xSum + sum(x * xList_1)
        return xSum
谢谢你的帮助

注意:如果你想知道,我正试图用熊猫来实现

In [14]: x = [9, 13, 10, 5, 3]

In [15]: np.triu(np.outer(x, x), k=1).sum()
Out[15]: 608
但我同意@user2357112的答案

x = array([9, 13, 10, 5, 3])
result = (x.sum()**2 - x.dot(x)) / 2
与其他可能具有二次性能的解决方案相比,它利用一些数学简化在线性时间和恒定空间中工作

这是一张工作原理图。假设
x=array([2,3,1])
。然后,如果将产品视为矩形区域:

x is this stick: -- --- -

x.sum()**2 is this rectangle:
   -- --- -
  |xx xxx x
  |xx xxx x

  |xx xxx x
  |xx xxx x
  |xx xxx x

  |xx xxx x

x.dot(x) is this diagonal bit:
   -- --- -
  |xx
  |xx

  |   xxx
  |   xxx
  |   xxx

  |       x

(x.sum()**2 - x.dot(x)) is the non-diagonal parts:
   -- --- -
  |   xxx x
  |   xxx x

  |xx     x
  |xx     x
  |xx     x

  |xx xxx

and (x.sum()**2 - x.dot(x)) / 2 is the product you want:
   -- --- -
  |   xxx x
  |   xxx x

  |       x
  |       x
  |       x

  |

看起来您希望获得该列表中两个元素(对)的每个组合,计算每对元素的乘积,并对这些乘积求和:

import itertools

xlist = [9, 13, 10, 5, 3]
pairs = itertools.combinations(xlist, 2)
answer = 0
for pair in pairs:
    answer += pair[0] * pair[1]
要做到这一点,需要一个班轮:

import itertools
import operator

sum(operator.mul(*t) for t in itertools.combinations(xlist, 2))
一种方法-

xarr = np.array(xList)

N = xarr.size
range1 = np.arange(N)

mask = range1[:,None] < range1
out = ((mask*xarr)*xarr[:,None]).sum()
xarr=np.array(xList)
N=xarr.size
范围1=np.arange(N)
掩码=范围1[:,无]
另一个-

xarr = np.array(xList)

N = xarr.size
range1 = np.arange(N)

R,C = np.where(range1[:,None] < range1)
out = (xarr[R]*xarr[C]).sum()
xarr=np.array(xList)
N=xarr.size
范围1=np.arange(N)
R、 C=np.其中(范围1[:,无]
您实际上想要的是组合而不是产品:

from itertools import combinations

print(sum(a*b for a,b in combinations(xList,2)))
608
即使从python列表中创建一个numpy数组,answer也会和我们一起扫地出门

In [38]: timeit sum(a*b for a,b in combinations(xlist,2))
10000 loops, best of 3:
89.7 µs per loop

In [40]: timeit sum(mul(*t) for t in itertools.combinations(xlist, 2))
1000 loops, best of 3:
165 µs per loop

In [41]: %%timeit                                        
x = array(arr)
(x.sum()**2 - (x**2).sum()) / 2
   ....: 
100000 loops, best of 3:
 10.9 µs per loop

In [42]: timeit np.triu(np.outer(x, x), k=1).sum()
10000 loops, best of 3:
48.1 µs per loop
In [59]: %%timeit
....: xarr = np.array(xList)
....: N = xarr.size
....: range1 = np.arange(N)
....: mask = range1[:,None] < range1
....: out = ((mask*xarr)*xarr[:,None]).sum()
10000 loops, best of 3: 30.4 µs per loop

但是对于大型阵列,numpy解决方案的速度仍然要快得多。

如果您有兴趣手动执行此操作(无需stdlib的帮助):


个人好奇心(查阅文献),使用这种可实现性比使用更流行的可实现性有什么好处?实际上,这是大多数其他人看到的衡量标准,为什么你不使用标准库?有时,人们对解决问题的算法感兴趣,而不仅仅是快速的一行。这正是为什么我在回答的开头都加上了“如果你有兴趣手工做这件事”,并添加了明确要求使用
itertools
numpy
@chepner解决的问题:我已经添加了这样一个答案。然而,未来的用户可能仍然对这个答案感兴趣,即使OP不感兴趣。这正是我将此解决方案作为一个单独的解决方案发布的原因answer@chepner:嗯,“也许有”不足以排除其他答案,嗯。@WarrenWeckesser:哎呀。修正了,天哪。数学有时很有用,是吧?比itertools快了一英里,你能解释一下它是如何工作的吗?@Padraickinningham:我试着做一些ASCII艺术图表。它们有帮助吗?另一种解释为什么这样做的方法是:从总和的平方开始,比如(a+b+c+d)^2。这扩展为一系列术语(放入WolframAlpha中查看)。我们需要所有的项,除了元素平方的项,所以这些项需要减去。剩下的项都乘以2,所以除以它,我们就剩下我们想要的了。谢谢。itertools.compositions是我所缺少的。我选择了user2357112答案,因为它更全面地解释了这个问题。
In [63]: timeit result = (sum(xList)**2 - sum(x ** 2 for x in xList)) / 2
100000 loops, best of 3: 
4.63 µs per loop
def combinations(L):
    for i,elem in enumerate(L):
        for e in L[i+1:]:
            yield (elem, e)

def main(xlist):
    answer = 0
    for a,b in combinations(xlist):
        answer += a*b
    return answer