Tensorflow : Get indices of array rows which are zero - arrays

For a tensor
[[1 2 3 1]
[0 0 0 0]
[1 3 5 7]
[0 0 0 0]
[3 5 7 8]]
how can I get the indices of the 0 rows? I.e. the list [1,3], in Tensorflow?

As far as I know, you can't really do that in one command like you would with a more advanced library like NumPy.
If you really want to use TF functions I could suggest a few like:
x = tf.Variable([
[1,2,3,1],
[0,0,0,0],
[1,3,5,7],
[0,0,0,0],
[3,5,7,8]])
y = tf.Variable([0,0,0,0])
condition = tf.equal(x, y)
indices = tf.where(condition)
This would result the following:
[[1 0]
[1 1]
[1 2]
[1 3]
[3 0]
[3 1]
[3 2]
[3 3]]
Or you could use the following if you just want to get only the zero lines:
row_wise_sum = tf.reduce_sum(tf.abs(x),1)
select_zero_sum = tf.where(tf.equal(row_wise_sum,0))
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(select_zero_sum))
The result being:
[[1]
[3]]

It can be done in an easier way too:
g = tf.Graph()
with g.as_default():
a = tf.placeholder(dtype=tf.float32, shape=[3, 4])
b = tf.placeholder(dtype=tf.float32, shape=[1, 4])
res = tf.not_equal(a, b)
res = tf.reduce_sum(tf.cast(res, tf.float32), 1)
res = tf.where(tf.equal(res1, [0.0]))[0]
with tf.Session(graph=g) as sess:
sess.run(tf.global_variables_initializer())
dict_ = {
a:np.array([[2.0,6.0,3.0,2.0],
[1.0,8.0,32.0,1.0],
[1.0,8.0,3.0,11.0]]),
b:np.array([[1.0,8.0,3.0,11.0]])
}
print(sess.run(res, feed_dict=dict_))
:[2]

Related

Go: nested loop causes scope issue

I have some code in golang which is suppose to discover the next possibilities in a Tic-Tac-Toe board.
This is the buggy part:
var next []State
for row := 0; row < len(board); row++ {
for place := 0; place < len(board[row]); place++ {
if board[row][place] == 0 {
nPos := board
fmt.Print(nPos)
nPos[row][place] = play
fmt.Print(nPos, row, place, play, "\n")
next = append(next, nPos)
}
}
}
State is a type of [][]int.
board is a State, play is an int and next is a []State .
The output is as follows:
[[0 0 0] [0 0 0] [0 0 0]][[1 0 0] [1 0 0] [1 0 0]] 0 0 1
[[1 0 0] [1 0 0] [1 0 0]][[1 1 0] [1 1 0] [1 1 0]] 0 1 1
[[1 1 0] [1 1 0] [1 1 0]][[1 1 1] [1 1 1] [1 1 1]] 0 2 1
[[[1 1 1] [1 1 1] [1 1 1]] [[1 1 1] [1 1 1] [1 1 1]] [[1 1 1] [1 1 1] [1 1 1]]]
You can clearly see two things:
One iteration changes the whole column (I guess it has to do with the outer loop, row)
For some reason the changes are saved (nPos is not reinitialized through iterations)
I am somewhat new to Go, am I wrong when expect nPos to be a new variable in every iteration?
I have already looked for issues in the line nPos[row][place] = play, but apparently no specific line causes the issue. I guess it is just the scope.
As #zerkms pointed out:
nPos := board <--- here both nPos, and board contain the same slice, Go does not implicitly do a deep slice copy. If you want a duplicate of a slice - you should manually clone it.
One option is:
cpy := make([]T, len(orig)) copy(cpy, orig)
Other answers are here:
Concisely deep copy a slice?

Method to convolve a 4D array with a 2D array (different kernel for each element)?

I would like to do a convolution using a different kernel for each element. My signal array has the shape n x m and the kernels have the shape [i, i]. I have the kernels in a 4D array of shape n x m x i x i, such that the value at [x, y] is the i x i kernel to apply to the element at [x, y] in the signal array. For example:
2D signal array:
[[0 1]
[5 9]]
4D kernel array, having a different 3x3 kernel for each signal array element:
[[[[1 0 1] | [[0 0 0]
[0 1 0] | [0 0 0]
[1 0 1]] | [0 0 0]]
------------------------
[[1 1 1] | [[0 1 0]
[1 1 1] | [1 0 1]
[1 1 1]] | [0 1 0]]]]
Desired "convolution" process:
[[1 0 1] [[- - -] [[0 0 0] [[- - -]
[0 1 0] • [- 0 1] = 9 [0 0 0] • [0 1 -] = 0
[1 0 1]] [- 5 9]] [0 0 0]] [5 9 -]]
[[1 1 1] [[- 0 1] [[0 1 0] [[0 1 -]
[1 1 1] • [- 5 9] = 15 [1 0 1] • [5 9 -] = 6
[1 1 1]] [- - -]] [0 1 0]] [- - -]]
Desired result:
[[9 0]
[15 6]]
I can do this by looping over each convolution window, but that's slow for large arrays:
def fancy_convolve(signal, kernels):
kernel_size = kernels[0][0][0].shape[0]
pad_width = int(kernel_size / 2)
padded_signal = numpy.pad(signal, pad_width, 'constant',
constant_values=0)
output = numpy.empty(signal.shape)
for x in range(signal.shape[0]):
for y in range(signal.shape[1]):
signal_window = padded_signal[x:x+kernel_size, y:y+kernel_size]
kernel = kernels[x, y]
output[x, y] = numpy.dot(
signal_window.flatten(), kernel.flatten())
return output
Is there a function to do this efficiently in numpy, scipy, or another library? Is convolution the right word for it? I've looked at scipy.ndimage.convolve and scipy.signal.convolve, which allow higher dimensions but still only one kernel, and numpy.tensordot, which doesn't do the sliding window part of convolution. Thanks!
To make it straightforward without additional consideration about the layout of the arrays. I would combine a stride trick and an Einsteing sum.
def efficient_fancy_convolve(signal, kernels):
kernel_size = kernels[0][0][0].shape[0]
pad_width = int(kernel_size / 2)
padded_signal = numpy.pad(signal, pad_width, 'constant',
constant_values=0)
p1 = numpy.lib.stride_tricks.as_strided(
padded_signal, kernels.shape, 2*padded_signal.strides)
return np.einsum('xyjk,xyjk->xy', p1, kernels)
Then a quick test
x = np.random.randn(1000, 1000)
kernels = np.random.randn(1000, 1000, 10, 10)
x1 = fancy_convolve(x, kernels) # 3.7s
x2 = efficient_fancy_convolve(x, kernels) # 139ms
assert np.allclose(x1, x2)

Numpy: How to replace a column in numpy array with another column? Why this emample doesn't work?

I would like to replace a column of a numpy array with another array conditionally, a sample example is shown here:
import numpy as np
t = np.asarray([[1,0,0],[1,0,0],[2,0,0],[3,0,0]])
print(t):
[[1 0 0]
[1 0 0]
[2 0 0]
[3 0 0]]
# replace
t[t[:,0]==1][:,1] = np.asarray([2,3])
print(t) again:
[[1 0 0]
[1 0 0]
[2 0 0]
[3 0 0]]
what I want to get is:
t =
[[1 2 0]
[1 3 0]
[2 0 0]
[3 0 0]]
After assigning the new value [2,3], t doesn't change. Does anyone knows how to get the new t?
Thanks in advance!

How do I input x,y,z co-ordinates as a single element inside a matrix?

I am trying to create a bezier surface using MATLAB code. For this I have to input co-ordinates in the form of [[x1 y1] [x2 y2] [x3 y3];[x4 y4] [x5 y5] [x6 y6]]. I have tried using cell array but arithmetical operations with other matrices or array isn't possible while using cell array. Please help
example:
C=[[2 3] [3 4] [4 5] [5 6];[2 5] [5 2] [7 8] [8 9]];
A=C(1,3);
ans=[4 5]
Also
C=[[2 3] [3 4] [4 5] [5 6];[2 5] [5 2] [7 8] [8 9]];
D=[1 2;2 1;3 1;2 3];
E=C*D
ans=[[30 38] [26 33];[49 51] [40 47]]
you can try using cat(3,..):
C = cat(3,[[2 3] ;[3 4] ;[4 5]; [5 6]],[[2 5]; [5 2] ;[7 8] ;[8 9]]);
A = C(3,:,1)
You could use a 3D matrix, with the second "layer" being your second coordinate pair, or simply use 2 matrices!
Using your example:
C1 = [2 3 4 5; 2 5 7 8];
C2 = [3 4 5 6; 5 2 8 9];
D = [1 2; 2 1; 3 1; 2 3];
E1 = C1*D; E2 = C2*D;
In 3D matrices:
% Make 3D matrix of same size as C1 but 2 layers
C = zeros([size(C1), 2]);
C(:,:,1) = C1; C(:,:,2) = C2;
E = cat(3, C(:,:,1)*D, C(:,:,2)*D);
% ans is a 3D matrix, with the 2 layers representing the pairs in your example.
Indexing the 3D matrix like you wanted:
C13 = reshape(C(1,3,:),1,2) % C13 = [4, 5]
% or
C13 = squeeze(C(1,3,:))' % C13 = [4, 5]

Slice array of arbitrary dimension with lists of start and end indices

I need to copy a part of a 3D array.
I have the indexes of start and end of the copy.
For example 2D array:
[[2 2 3 4 5]
[2 3 3 4 5]
[2 3 4 4 5]
[2 3 4 5 5]
[2 3 4 5 6]]
starting index, end index are:
mini = [2, 1]
maxi = [4, 3]
So the result should be:
[[3 4 4]
[3 4 5]]
I can write:
result = matrix[mini[0]:maxi[0], mini[1]:maxi[1]]
Is there a way to do it generally ? for 3Dim or NDim arrays ?
The trick here is realizing what the indexing syntax is under the hood. This:
result = matrix[mini[0]:maxi[0], mini[1]:maxi[1]]
Is shorthand in python (not just numpy) for:
indices = slice(mini[0], maxi[0]), slice(mini[1], maxi[1])
result = matrix[indices]
So we just need to generate indices dynamically:
lower = [2, 1, ...]
upper = [4, 3, ...]
indices = tuple(np.s_[l:u] for l, u in zip(lower, upper))
result = matrix_nd[indices]
np.s_[a:b] is a shorthand for slice(a, b). Here we build a tuple containing as many slices as you have values in lower and upper
What you are looking for is the slice object, see that example:
matrix = np.random.rand(4,5)
mini = [2, 1]
maxi = [4, 3]
slices=[slice(b,e) for b, e in zip(mini,maxi)]
print(slices)
print(matrix[slices])
print(matrix[mini[0]:maxi[0], mini[1]:maxi[1]])

Resources