2014-02-06 4 views
1

, скажем, у меня есть два массива numpy a = (n x m) и b = (z x m), где столбцы m являются некоторым общим идентификатором.Слияние двух массивов по столбцу

a = np.array([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 0, 1], [1, 1, 0, 1]]) 
b = np.array([[1, 0, 0, 1], [1, 1, 0, 1], [0, 1, 1, 0]]) 

есть ли NumPy-иш способ получить c = (n x z) где c_ij = 1 if (any element in (row i of a AND row j of b) is equal to 1) else 0 без петель, так что в этом случае

c = np.array([[1, 1, 0], [1, 1, 1], [1, 1, 0], [1, 1, 1]]) 
+0

Вы можете разместить версию на основе цикла этого, который возвращает тот же результат? –

ответ

2

IIUC, вы могли бы смотреть на это как матричное умножение:

>>> a = np.array([[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 0, 1], [1, 1, 0, 1]]) 
>>> b = np.array([[1, 0, 0, 1], [1, 1, 0, 1], [0, 1, 1, 0]]) 
>>> (a.dot(b.T) > 0).astype(int) 
array([[1, 1, 0], 
     [1, 1, 1], 
     [1, 1, 0], 
     [1, 1, 1]]) 

Недостатком является то, что этот подход делает намного больше работы, чем нужно, потому что он выполняет все умножение. Если производительность действительно важна (и это очень важно реже, чем люди считают ее критическим), вы можете написать немного cython или использовать numba, чтобы вернуть поведение короткого замыкания с C-подобной скоростью. Один из местных мастеров numpy, вероятно, подумает о чем-то умном. : ^)

+0

Если numpy скомпилирован с приличным BLAS, это будет очень сложно обыграть с чистым numpy, поскольку функция «any» numpy (IIRC) не разбивается на первую истину и вместо этого зашифровывает весь массив. Возможно, вы сможете сделать немного лучше, если вы вызовете «SGEMM» прямо через scipy. – Daniel

0

Я знаю, что вы сказали, без петель, но это работает:

np.array([[np.any(x&y) for x in a] for y in b],dtype=int).T 
Смежные вопросы