Reputation: 1962
Right now I have a NumPy
array of 0
's and 1
's and I want to perform a logical_and
on every two columns. A for
loop achieving this would look as follows:
import numpy as np
result = []
data = [[0, 1, 1],
[1, 0, 1],
[1, 0, 1]]
np_data = np.array(data)
num_cols = len(np_data[1,:])
for i in range(0, num_cols):
for j in range(i+1, num_cols):
#Comparing every column with every other column
anded = np.logical_and(np_data[:,i], np_data[:,j])
result.append(anded)
print result
I was just wondering whether there was a NumPy
-fied way to do this since obviously for
loops are not good for operating on NumPy
arrays.
Upvotes: 2
Views: 1298
Reputation: 27028
I'm sure there's a smarter way to construct the index lists ii,jj but this does the same as your code for your example:
import numpy as np
data = [[0, 1, 1],
[1, 0, 1],
[1, 0, 1]]
np_data = np.array(data)
q=range(len(data))
ii,jj=zip(*[[i,j] for i in q for j in q if i<j])
result=np.transpose(np.logical_and(np_data[:,list(ii)],np_data[:,list(jj)]))
Edit: for ii,jj
you can also use this (inspired by Bago):
ii,jj = np.array(list(combinations(q, 2))).T
Upvotes: 0
Reputation: 6878
Assume you have an array (n,m) with n rows and m columns, then you can get the logical and between all possible columns as an array (m,m) where each element is an array of size n. This is similar to your result, but double the size (no triangular matrix).
import numpy as np
data = np.array([[0, 1, 1],
[1, 0, 1],
[1, 0, 1]])
n,m = data.shape
dist0 = np.tile(data.T,(m,1)).reshape(m,m,n) # repeat columns along axis 0
dist1 = np.tile(data.T,(1,m)).reshape(m,m,n) # repeat columns along axis 1
result = np.logical_and(dist0, dist1)
# now result[i,j] contains the logical_and bewteen column i and j
print(result[0,2])
[False True True]
Upvotes: 0
Reputation: 25823
You can do it like this, notice that result is the transpose of your result (Also in this case result is a 2d array and in your case it is a list of 1darrays).
>>> from itertools import combinations
>>> I, J = np.array(list(combinations([0,1,2], 2))).T
>>> result = np.logical_and(np_data[:, I], np_data[:, J])
>>> result
array([[False, False, True],
[False, True, False],
[False, True, False]], dtype=bool)
>>> result.T
array([[False, False, False],
[False, True, True],
[ True, False, False]], dtype=bool)
Upvotes: 1