2016-10-14 2 views
-1

내가 좋아하는 빅 데이터가 있습니다. 'a'의 행은 하위 행에 의해 절대로 중복되지 않습니다. 가장 일치하는 값의 관점에서 2 개 (ab, ac) 또는 3 개 (abc) 이상의 행을 가장 효과적으로 조합하려면 어떤 효과가 있습니까? 희망, 여하튼, 질문을 명확하게 설명하기가 어렵습니다 :/ 어쩌면 numpy의 일부 매트릭스 작업?파이썬 매트릭스 비교

자세한 정보 : 가능한 조합은 ab, ac, bc입니다. ab는 a (a_1, a_2, a_3)의 행을 b (b_1, b_2)의 행에 대해 서로 검사합니다. a_1 & b_1은 0b110000 & 0b100100을 의미하고 하나의 결과를 제공합니다. a_1 & b_2는 0b110000 & 0b000001을 의미하며 결과가 없습니다. 이는 루프 별 솔루션에 대한 설명이지만, 특히 8 개 정도의 조합 (예제 데이터로는 다루지 않음)에서 매우 느립니다.

어쩌면 데이터의 더 명확 구조 : 나는 지금까지 그 계산을하고 있어요 방법

{'a': [0b110000, 
     0b001100, 
     0b000011], 
'b': [0b100100, 
     0b000001], 
'c': [0b100000]} 

는 나에게 쇼를 보자. 데이터 구조는 ... 이것에

data = {'a':[1,1,2,2,3,3], 
     'b':[4,5,5,5,4,5], 
     'c':[6,7,7,7,6,7]}  

combine_count = 3 
for config in combinations(['a','b','c'],combine_count): 
    ret = {} 
    for index,combined in enumerate(zip(*tuple(data.get(k) for k in config))): 
     ret.setdefault(combined, []).append(index) 

for k,v in ret.items(): 
    score = len(v) 
    if score >= 2: 
     print(k,score) 

내 문제가 큰 combine_count과 함께 건설의 특히 과정 종류의 서로 다른, 더 나은 구조 '생각'은 함께이 질문을 시작하려고 같다 많은 시간이 걸린다. 물론 데이터가 훨씬 큽니다. 그것에는 길이 약 ~ 60000의 목록이있는 약 231 개의 키가 있습니다. 또한 RAM 소비가 너무 높습니다.

+0

데이터 예제를 사용하여 달성 한 결과를 정확히 보여줍니다. (ab, ac) 및 (abc)는 아무데도 등장하지 않았으며 큰 데이터와 직접적으로 관련이 없습니다. – paddyg

+0

가 더 많은 정보를 추가했습니다. 희망, 그게 도움이됩니다. –

+0

그러면 a1 & b1-> 16, a1 & b2-> 0, a2 & b1-> 4, a2 & b2-> 0, a3 & b1-> 0, a3 & b2-> 1이됩니다. 트리플 버전의 경우 평가는 a1 & b1 | a1 & c1 | b1 & c1? – paddyg

답변

1

당신의 트리플 평가에 ​​대해서는 잘 모르겠지만 * 당신이 원하는 것을하기 위해 이것을 수정할 수도 있습니다. I는 (A)의 조합, B, C 등을 반복한다고 가정하고

#!/usr/bin/python 
import numpy as np 
import random 
import time 

A = [np.random.randint(0, 2**15, random.randint(1, 5)) + 2**16 for i in range(231)] 
best_score = 0 
tm = time.time() 
for i, a in enumerate(A): 
    for j, b in enumerate(A[1:]): 
    for k, c in enumerate(A[2:]): 
     an, bn, cn = len(a), len(b), len(c) #some shortcuts 

     a_block = np.broadcast_to(a.reshape(an, 1, 1), (an, bn, cn)) 
     b_block = np.broadcast_to(b.reshape(1, bn, 1), (an, bn, cn)) 
     c_block = np.broadcast_to(c.reshape(1, 1, cn), (an, bn, cn)) 

     all_and = c_block & b_block & a_block 

     all_score = ((all_and & 1) + 
        ((all_and >> 1) & 1) + 
        ((all_and >> 2) & 1) + 
        ((all_and >> 3) & 1) + 
        ((all_and >> 4) & 1) + 
        ((all_and >> 5) & 1)) 
     ix = np.unravel_index(np.argmax(all_score), (an, bn, cn)) 
     if all_score[ix] > best_score: 
     print(i,j,k, ix, all_score[ix], a_block[ix], b_block[ix], c_block[ix]) 
     best_score = all_score[ix] 
     best_abc = (i, j, k) 
     best_ix = ix[:] 

print(time.time() - tm) 
print(best_score) 
print(best_abc) 
print(best_ix) 
''' gives 
0 0 0 (0, 2, 0) 2 95038 76894 78667 
0 0 1 (0, 3, 1) 3 95038 70262 96242 
0 0 2 (0, 2, 0) 4 95038 76894 96255 
0 3 2 (0, 0, 0) 5 95038 96255 96255 
4 3 2 (0, 0, 0) 6 96255 96255 96255 
871.6093053817749 
6 
(4, 3, 2) 
(0, 0, 0) 
''' 

EDIT *이 코드는 않는다 생각 : 위치 (그리고 값) (A1) 사이의 최대 & B1 & C1, A2를 찾을 & & B1, C1, B1 A3 & & C1, B2 & & A1 B1 C1 A1 등 & & C1에서 다른 가능성있는 | a2 & b1 & c1 | a3 & b1 & c1 | A1 B2 & & C1

EDIT2 세부 명시 의사 세트 반복하는 과정을 도시. a, b, c는 배열 1에서 5까지 길지만 numpy randint는 60000 비트의 난수를 생성 할 수 없습니다. 또한 모든 숫자가 고유한지 확인하려고 시도하지 않았습니다. (매우 쉽게 할 수 있습니다) 약 15m 이것에 아주 강력한 랩톱이 아니라, 그래서 당신에게 비교를위한 출발점을 제공합니다.

프로세스를 가속화하는 방법은 비교를 단지 두 가지로 한정하는 것일 수 있습니다. 예를 들어 a, b는 높은 점수를받은 사람의 목록을 유지 한 다음 해당 조합의 각각을 통과합니다. & ing 목록에서 가장 높은 점수를 3 가지 방법으로 선택합니다.

+0

답장을 보내 주셔서 감사합니다 :). 확인해 볼 시간이 필요합니다. 하지만 그 결과를 설명해 주시겠습니까? 나는 그것이 무엇을 의미하는지 확실히 모르겠다. 그런데, 입력 데이터가 이진수 일 필요는 없다는 것을 나는 알아야한다. 그들은 단지 a, b, c의 다른 값의 위치를 ​​표시하고 있습니다. 여기 –

+0

는 응답의 출력이고 : [1 0 0] [0 0 0 0] [0 0 1] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] (0, 0, 0) –

+0

@SvenLange 좋아, 어쩌면 그렇게 명확한 일치 예제가 아니었을 것입니다. 두 개의 숫자를 0,0,0이 아닌 2 비트 일치로 변경하고 더 많은 설명을 추가했습니다. 잘하면 지금은 분명해. (all_or를 all_and로 이름을 바꾼 이유는 '이전에'또는 '이전에 호출 한 이유를 모르겠습니다.) – paddyg