import jax.numpy as jnp
vectors and array are jnp.array(dtype=jnp.int32)
I have an array with shape [x, d, y] (3x3x3)
[[[0 0 0],
[0 0 0],
[0 0 0]],
[[0 0 0],
[0 0 0],
[0 0 0]],
[[0 0 0],
[0 0 0],
[0 0 0]]]
and vectors x = [2 0 3], y = [ 2 0 1], d = [0 0 1]
I want to have something like this by indexing but I tried and don't really know how, with jax.numpy.
[[[0 0 2],
[0 0 0],
[0 0 0]],
[[0 0 0],
[0 0 0],
[0 0 0]],
[[0 0 0],
[0 3 0],
[0 0 0]]]
Edit: I would like to specify that I wanted to put number from x with its index to the array but only when x > 0. I tried with boolean mask.
Something like this
mask = x > 0
array = array.at[mask, d, y].set(array[mask, d, y] + x)
You have a three-dimensional array, so you can index it with three arrays of indices. Since you want d and y to be associated with the second and third dimensions, you'll need to create another array of indices for the first dimension:
import jax.numpy as jnp
arr = jnp.zeros((3, 3, 3), dtype='int32')
x = jnp.array([2, 0, 3])
y = jnp.array([2, 0, 1])
d = jnp.array([0, 0, 1])
i = jnp.arange(len(x))
mask = x > 0
out = arr.at[i[mask], d[mask], y[mask]].set(x[mask])
print(out)
# [[[0 0 2]
# [0 0 0]
# [0 0 0]]
# [[0 0 0]
# [0 0 0]
# [0 0 0]]
# [[0 0 0]
# [0 3 0]
# [0 0 0]]]
In this case the result will be the same whether or not you use the mask (i.e. arr.at[i, d, y].set(x) will give the same result) but because your question explicitly specified that you only want to use values x > 0 I included it.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a matrix of 0 and 1, example:
X =
[[1, 1, 0, 0],
[1, 0, 1, 1],
[0, 0, 1, 1],
[1, 1, 1, 1],
In each row, choose only an '1' and leave orthers become 0, to get the same number of '1' in each colunm. Basically, minimum variance after get sum by columns.
Example: From X above, the answer is:
Y =
[[1, 0, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
Each column in Y have a '1'. Y choose 1st '1' from row 1 of X, choose 2nd '1' in index 4 from row 2,.... X can have any size.
How can i do that?
Sorry for my bad english.
EDIT: what follows is a brute force technique which finds every "solution". It does not work for non-square arrays because OP's problem is vague on how non-square arrays should be treated. The technique I have in mind for finding a random solution is just a simple backtracking algorithm over idxs, which I may get around to tomorrow if somebody else doesn't come up with something better.
Here's a brute force solution which takes the cartesian product of the column indices where there is a one for each row:
import itertools
import numpy as np
x = np.array([[1, 1, 0, 0],
[1, 0, 1, 1],
[0, 0, 1, 1],
[1, 1, 1, 1]])
n = x.shape[1]
rows, cols = np.argwhere(x).T
idxs = np.split(cols, np.unique(rows, return_index=True)[1][1:])
col_idxs = [t for t in itertools.product(*idxs) if len(set(t)) == n]
row_idxs = np.arange(n)
Showing all solutions for this particular X:
for t in col_idxs:
z = np.zeros_like(x)
z[row_idxs, t] = 1
print(f"{z}\n")
Output:
[[1 0 0 0]
[0 0 1 0]
[0 0 0 1]
[0 1 0 0]]
[[1 0 0 0]
[0 0 0 1]
[0 0 1 0]
[0 1 0 0]]
[[0 1 0 0]
[1 0 0 0]
[0 0 1 0]
[0 0 0 1]]
[[0 1 0 0]
[1 0 0 0]
[0 0 0 1]
[0 0 1 0]]
[[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
[1 0 0 0]]
[[0 1 0 0]
[0 0 0 1]
[0 0 1 0]
[1 0 0 0]]
I have 2 tensors:
h=[[0 0 0]
[0 0 1]
[0 1 0]]
and
h2=[[0 0 0]
[0 0 1]
[0 0 1]]
I want to create 3 vector with values where h=h2
I mean ,i want compare h[0]=h2[0] ,h[1]=h2[1] and h[2]=h2[2]
So I want the 3 vector as:
h3=[[0 0 0]
[0 0 1]
I tried :
def fn( tensor1,i):
return tensor1[i]
tensor = [fn(h,i) for i in range(h) if tf.reduce_all(tf.equal(h[i],h2[i])) ]
but it return this error TypeError: only integer scalar arrays can be converted to a scalar index
Working code snippet
import tensorflow as tf
h=[[0,0 ,0],
[0, 0 ,1],
[0, 1 ,0]]
h2=[[0 ,0 ,0],
[0 ,0, 1],
[0, 0, 1]]
for i in range(len(h)):
if tf.reduce_all(tf.equal(h[i],h2[i])):
print(h[i])
Output
[0, 0, 0]
[0, 0, 1]
I'm trying to check elements of a 2D array (matrix) and generate a number of matrices (of equal size) depending on some conditions as below:
Consider my matrix:
x = [[1, 0, 2],[7, 0, 7],[1, 1, 1]]
I need to check for the (2) and generate two matrices where the position of (2) will be replaced by 0 and 1 respectively. I also need to check for the 7's and generate 3 combinations of the matrix with values of 7 being (0,1),(1,0),(1,1) respectively. This mean the total number of matrices generated are 6 as follows:
[[1, 0, 0],[0, 0, 1],[1, 1, 1]]
[[1, 0, 0],[1, 0, 0],[1, 1, 1]]
[[1, 0, 0],[1, 0, 1],[1, 1, 1]]
[[1, 0, 1],[0, 0, 1],[1, 1, 1]]
[[1, 0, 1],[1, 0, 0],[1, 1, 1]]
[[1, 0, 1],[1, 0, 1],[1, 1, 1]]
There can be more than 1 (2), and the position of 7's can be vertical or hirizental.
I've tried a naiive way just looping through x looking for 2's and appending:
for i in range(len(x)):
for j in range(len(x[0])):
if x[i][j] == 2:
inter[i][j] = 0
test.append(inter)
inter2[i][j] = 1
test.append(inter2)
But that only works if I have the value of 2 only. I've also tried converting to numpy array and using where() to find the indexes of 2's and 7's, but then don't know how that can be used to generate the required outcome. Any thoughts?
The conditions described are very vague. If I understand correctly, you want this:
sevens = [[0,1],[1,0],[1,1]]
twos = [0,1]
for i in twos:
for j in sevens:
m = x.copy()
m[m==2] = i
m[m==7] = j
print(m)
output:
[[1 0 0]
[0 0 1]
[1 1 1]]
[[1 0 0]
[1 0 0]
[1 1 1]]
[[1 0 0]
[1 0 1]
[1 1 1]]
[[1 0 1]
[0 0 1]
[1 1 1]]
[[1 0 1]
[1 0 0]
[1 1 1]]
[[1 0 1]
[1 0 1]
[1 1 1]]
UPDATE: per OP's comment for (2)s multiplicities:
x = np.array([[2, 0, 2],[7, 0, 7],[1, 1, 1]])
sevens = [[0,1],[1,0],[1,1]]
v = (x==2).sum()*([0,1],)
twos = np.array(np.meshgrid(*v)).T.reshape(-1,2)
for i in twos:
for j in sevens:
m = x.copy()
m[m==2] = i
m[m==7] = j
print(m)
output:
[[0 0 0]
[0 0 1]
[1 1 1]]
[[0 0 0]
[1 0 0]
[1 1 1]]
[[0 0 0]
[1 0 1]
[1 1 1]]
[[0 0 1]
[0 0 1]
[1 1 1]]
[[0 0 1]
[1 0 0]
[1 1 1]]
[[0 0 1]
[1 0 1]
[1 1 1]]
[[1 0 0]
[0 0 1]
[1 1 1]]
[[1 0 0]
[1 0 0]
[1 1 1]]
[[1 0 0]
[1 0 1]
[1 1 1]]
[[1 0 1]
[0 0 1]
[1 1 1]]
[[1 0 1]
[1 0 0]
[1 1 1]]
[[1 0 1]
[1 0 1]
[1 1 1]]
import numpy as np
arr = np.array([[0, 1, 0],
[1, 0, 0],
[1, 0, 0]])
mask = arr
print('boolean mask is:')
print(mask)
print('arr[mask] is:')
print(arr[mask])
Result:
boolean mask is:
[[0 1 0]
[1 0 0]
[1 0 0]]
arr[mask] is:
[[[0 1 0]
[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]
[0 1 0]]
[[1 0 0]
[0 1 0]
[0 1 0]]]
I know how indexing works when the mask is 2-D, but confused when the mask is 3-D.
Anyone can explain it?
import numpy as np
l = [[0,1,2],[3,5,4],[7,8,9]]
arr = np.array(l)
mask = arr[:,:] > 5
print(mask) # shows boolean results
print(mask.sum()) # shows how many items are > 5
print(arr[:,1]) # slicing
print(arr[:,2]) # slicing
print(arr[:, 0:3]) # slicing
output
[[False False False]
[False False False]
[ True True True]]
3
[1 5 8]
[2 4 9]
[[0 1 2]
[3 5 4]
[7 8 9]]
Is there a way to get this result without a loop? I've made a couple attempts at fancy indexing with W[range(W.shape[0]),... but have been so far unsuccessful.
import itertools
import numpy as np
n = 4
ct = 2
one_index_tuples = list(itertools.combinations(range(n), r=ct))
W = np.zeros((len(one_index_tuples), n), dtype='int')
for row_index, col_index in enumerate(one_index_tuples):
W[row_index, col_index] = 1
print(W)
Result:
[[1 1 0 0]
[1 0 1 0]
[1 0 0 1]
[0 1 1 0]
[0 1 0 1]
[0 0 1 1]]
You can use fancy indexing (advanced indexing) as follows:
# reshape the row index to 2d since your column index is also 2d so that the row index and
# column index will broadcast properly
W[np.arange(len(one_index_tuples))[:, None], one_index_tuples] = 1
W
#array([[1, 1, 0, 0],
# [1, 0, 1, 0],
# [1, 0, 0, 1],
# [0, 1, 1, 0],
# [0, 1, 0, 1],
# [0, 0, 1, 1]])
Try this:
[[ 1 if i in x else 0 for i in range(n) ] for x in itertools.combinations( range(n), ct )]