列表中对的乘积之和
Sum of products of pairs in a list
这是我遇到的问题。给定一个列表
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
感谢任何帮助。
N.B:如果您想知道,我正在尝试使用 pandas
来实现 Krippendorf's alpha
这是一种方法:
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
与其他可能具有二次性能的解决方案相比,这利用了一些数学简化来以线性时间和常数工作space。
这是一个工作原理图。假设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
range1 = np.arange(N)
R,C = np.where(range1[:,None] < range1)
out = (xarr[R]*xarr[C]).sum()
您实际上想要组合而不是产品:
from itertools import combinations
print(sum(a*b for a,b in combinations(xList,2)))
608
即使从 python 列表中创建一个 numpy 数组, 的答案也会让我们其他人一头雾水。
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
所有 lists/arrays 都有 50 个元素。
从 user2357112 窃取逻辑并将其用于总和 python 的普通列表非常有效:
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
但对于大型数组,numpy 解决方案仍然明显更快。
如果您有兴趣手动执行此操作(无需 stdlib 的帮助):
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
这是我遇到的问题。给定一个列表
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
感谢任何帮助。
N.B:如果您想知道,我正在尝试使用 pandas
来实现 Krippendorf's alpha这是一种方法:
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
与其他可能具有二次性能的解决方案相比,这利用了一些数学简化来以线性时间和常数工作space。
这是一个工作原理图。假设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
range1 = np.arange(N)
R,C = np.where(range1[:,None] < range1)
out = (xarr[R]*xarr[C]).sum()
您实际上想要组合而不是产品:
from itertools import combinations
print(sum(a*b for a,b in combinations(xList,2)))
608
即使从 python 列表中创建一个 numpy 数组,
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
所有 lists/arrays 都有 50 个元素。
从 user2357112 窃取逻辑并将其用于总和 python 的普通列表非常有效:
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
但对于大型数组,numpy 解决方案仍然明显更快。
如果您有兴趣手动执行此操作(无需 stdlib 的帮助):
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