2015-05-04 22 views
8

Đây là vấn đề tôi gặp phải. Cho một danh sáchTổng số sản phẩm của các cặp trong danh sách

xList = [9, 13, 10, 5, 3] 

Tôi muốn tính toán để tổng hợp của mỗi yếu tố nhân tố tiếp theo

sum([9*13, 9*10, 9*5 , 9*3]) + 
sum([13*10, 13*5, 13*3]) + 
sum([10*5, 10*3]) + 
sum ([5*3]) 

trong trường hợp này câu trả lời là .

Có cách nào để làm điều này có lẽ với itertools hoặc nguyên bản với numpy?

Dưới đây là chức năng tôi đã đưa ra. Nó làm công việc nhưng nó là xa lý tưởng như tôi muốn thêm các công cụ khác là tốt.

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 

Bất kỳ trợ giúp nào được đánh giá cao.

N.B: Trong trường hợp bạn tự hỏi, tôi đang cố gắng để thực hiện Krippendorf's alpha với gấu trúc

+0

tò mò cá nhân (nhìn vào văn học), những lợi ích của việc sử dụng realibility này trong những phổ biến hơn là gì? – PascalVKooten

+0

thực sự, biện pháp này được tổng quát hóa hầu hết những người khác, xem http://www.afhayes.com/public/cmm2007.pdf và http://www.agreestat.com/book4/ – user1043144

Trả lời

6

Dưới đây là một cách:

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

In [15]: np.triu(np.outer(x, x), k=1).sum() 
Out[15]: 608 

nhưng tôi muốn đi với câu trả lời @ user2357112 của.

25
x = array([9, 13, 10, 5, 3]) 
result = (x.sum()**2 - x.dot(x))/2 

Điều này tận dụng một số phép toán đơn giản để làm việc trong thời gian tuyến tính và không gian liên tục, so với các giải pháp khác có thể có hiệu suất bậc hai.

Đây là sơ đồ về cách hoạt động của tính năng này. Giả sử x = array([2, 3, 1]). Sau đó, nếu bạn xem các sản phẩm như các lĩnh vực hình chữ nhật:

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 

    | 
+3

Tốt vì tuyến tính. – DSM

+0

@WarrenWeckesser: Rất tiếc. Đã sửa. – user2357112

+2

Bejezes thánh. Toán đôi khi khá hữu ích, huh? – itzy

4

Dường như bạn muốn để có được tất cả các kết hợp của hai yếu tố (cặp) trong danh sách đó, tính toán các sản phẩm của mỗi cặp, và tổng hợp trên các sản phẩm này :

import itertools 

xlist = [9, 13, 10, 5, 3] 
pairs = itertools.combinations(xlist, 2) 
answer = 0 
for pair in pairs: 
    answer += pair[0] * pair[1] 

Các one-liner để làm điều này:

import itertools 
import operator 

sum(operator.mul(*t) for t in itertools.combinations(xlist, 2)) 
+0

cảm ơn bạn. Các itertools.combinations là những gì tôi đã thiếu. Tôi đã đi cho câu trả lời user2357112 vì nó giải thích vấn đề nói chung hơn. – user1043144

1

một cách tiếp cận -

xarr = np.array(xList) 

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

mask = range1[:,None] < range1 
out = ((mask*xarr)*xarr[:,None]).sum() 

Một số khác -

xarr = np.array(xList) 

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

R,C = np.where(range1[:,None] < range1) 
out = (xarr[R]*xarr[C]).sum() 
7

Bạn thực sự muốn kết hợp không sản phẩm:

from itertools import combinations 

print(sum(a*b for a,b in combinations(xList,2))) 
608 

Ngay cả việc tạo ra một mảng NumPy từ một danh sách python, @user2357112 câu trả lời lau sàn nhà với phần còn lại của chúng tôi.

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 

Tất cả danh sách/mảng có 50 phần tử.

Trộm cắp logic từ user2357112 và sử dụng nó trên một danh sách bình thường với tổng python là khá darn hiệu quả:

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 

Nhưng đối với một mảng lớn các giải pháp NumPy vẫn là nhanh hơn đáng kể.

1

Nếu bạn quan tâm trong việc này bằng tay (không có sự giúp đỡ từ 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 
+1

Tại sao bạn không sử dụng thư viện chuẩn? – chepner

+0

Một số lần, mọi người quan tâm đến thuật toán giải quyết vấn đề, nhiều hơn một lớp lót nhanh. Đó là lý do tại sao tôi cả hai bắt đầu câu trả lời của tôi với "nếu bạn quan tâm đến việc này bằng tay", và thêm [một câu trả lời nhiều pythonic] (http://stackoverflow.com/a/30039432/198633) – inspectorG4dget

+1

Câu hỏi một cách rõ ràng yêu cầu cho một giải pháp sử dụng 'itertools' hoặc' numpy'. – chepner

Các vấn đề liên quan