Related
I have a tensor, say
A = tensor([
[0, 0],
[0, 2],
[0, 3],
[0, 4],
[0, 5],
[0, 6],
[1, 0],
[1, 1],
[1, 4],
[1, 5],
[1, 6]
])
and the other tensor
b = tensor([[0, 2], [1, 2]])
I would like to find an efficient way to index into A by b such that the result is
result = tensor([[0, 3], [1, 4]])
That is, match A’s first column of last dim (i.e. [0,…,1…]) with b’s first column of the last dim (i.e. [0,1]) by their values and then use b’s second column (i.e. [2, 2]) to index A’s second column.
Thanks
Work out a solution by converting it to one dimensional problem with torch.nonzero and offset by mask sum.
Instead of the original A, get a flatten version, like
A = tensor([[ 0], [ 2], [ 3], [ 4], [ 5], [ 7], [ 8], [11], [12]])
and also calculate the offsets along batch,
offset = tensor([[0], [5], [4]])
Similarly, get b
b = tensor([2, 2])
and
offset_b = b+offset.reshape(-1)[:-1]
Then
indices=A.reshape(-1)[offset_b]
Good afternoon dear StackOverflow community,
I encounter a problem using MutableList in Kotlin. More specifically, I do not succeed to add a MutableList inside a MutableList.
For instance, with the example thereafter
fun main() {
var mutableListIndex: MutableList<Int> = mutableListOf<Int>()
var mutableListTotal: MutableList<MutableList<Int>> = mutableListOf<MutableList<Int>>()
for(i in 0..5) {
mutableListIndex.add(i)
println(mutableListIndex)
mutableListTotal.add(mutableListIndex)
println(mutableListTotal)
}
}
I get the following result
[0]
[[0]]
[0, 1]
[[0, 1], [0, 1]]
[0, 1, 2]
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[0, 1, 2, 3]
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
[0, 1, 2, 3, 4]
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
[0, 1, 2, 3, 4, 5]
[[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]
While, I am expecting the result thereafter
[0]
[[0]]
[0, 1]
[[0], [0, 1]]
[0, 1, 2]
[[0], [0, 1], [0, 1, 2]]
[0, 1, 2, 3]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]]
[0, 1, 2, 3, 4]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]]
[0, 1, 2, 3, 4, 5]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5]]
I do not succeed to understand where I am wrong as in my opinion the code from the stricly speaking algorythm point of view is good.
Can someone help and explain me my error ?
Yours faithfully
Following the advice of Sir Animesh Sahu above, I finally follow this solution:
fun main() {
var mutableListIndex: MutableList<Int> = mutableListOf<Int>()
var mutableListTotal: MutableList<MutableList<Int>> = mutableListOf<MutableList<Int>>()
for(i in 0..5) {
mutableListIndex.add(i)
println(mutableListIndex)
mutableListTotal.add(mutableListIndex.toMutableList())
println(mutableListTotal)
}
}
Which give:
[0]
[[0]]
[0, 1]
[[0], [0, 1]]
[0, 1, 2]
[[0], [0, 1], [0, 1, 2]]
[0, 1, 2, 3]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]]
[0, 1, 2, 3, 4]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]]
[0, 1, 2, 3, 4, 5]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4, 5]]
Thank you very much all for your prompt reply and your help
Yours faithfully
You always pass in the same reference of mutableListIndex to be added into mutableListTotal. So on every position you have the same object.
Then you add a new item into your first list and every reference to it points to the updated List, with one more item.
To get an independent object, that is not updated every time your first reference is updated, you first need to create a copy of the List and only add the copy into your second list. This way an update to your initial list will not be reflected into your copies of the first list.
import java.util.List.copyOf
fun main() {
...
mutableListTotal.add(copyOf(mutableListIndex))
...
}
I'm trying to concatenate 2 arrays element wise. I have the concatenation working to produce the correct shape but it has not been applied element wise.
So i have this array
[0, 1]
[2, 3]
[4, 5]
I want to append each element in the array with each element. the target result would be
[0, 1, 0, 1]
[0, 1, 2, 3]
[0, 1, 4, 5]
[2, 3, 0, 1]
[2, 3, 2, 3]
[2, 3, 4, 5]
[4, 5, 0, 1]
[4, 5, 2, 3]
[4, 5, 4, 5]
i think i may need to change an axis but then i can't get the broadcasting to work.
any help would be greatly appreciated. lots to learn in numpy !
a = np.arange(6).reshape(3, 2))
b = np.concatenate((a, a), axis=1)
One way would be stacking replicated versions created with np.repeat and np.tile -
In [52]: n = len(a)
In [53]: np.hstack((np.repeat(a,n,axis=0),np.tile(a,(n,1))))
Out[53]:
array([[0, 1, 0, 1],
[0, 1, 2, 3],
[0, 1, 4, 5],
[2, 3, 0, 1],
[2, 3, 2, 3],
[2, 3, 4, 5],
[4, 5, 0, 1],
[4, 5, 2, 3],
[4, 5, 4, 5]])
Another would be with broadcasted-assignment, since you mentioned broadcasting -
def create_mesh(a):
m,n = a.shape
out = np.empty((m,m,2*n),dtype=a.dtype)
out[...,:n] = a[:,None]
out[...,n:] = a
return out.reshape(-1,2*n)
One solution is to build on senderle's cartesian_product to extend this to 2D arrays. Here's how I usually do this:
# Your input array.
arr
# array([[0, 1],
# [2, 3],
# [4, 5]])
idxs = cartesian_product(*[np.arange(len(arr))] * 2)
arr[idxs].reshape(idxs.shape[0], -1)
# array([[0, 1, 0, 1],
# [0, 1, 2, 3],
# [0, 1, 4, 5],
# [2, 3, 0, 1],
# [2, 3, 2, 3],
# [2, 3, 4, 5],
# [4, 5, 0, 1],
# [4, 5, 2, 3],
# [4, 5, 4, 5]])
For example if my array was
(2,2)
array([[1, 0],
[0, 1]])
I would want it to return:
(4,2,2)
array([[[0, 0],
[0, 1]],
[[1, 1],
[0, 1]],
[[1, 0],
[1, 1]],
[[1, 0],
[0, 0]]])
You can flip binary number at a time using:
(np.identity(inp.size, int)^inp.ravel()).reshape(-1, *inp.shape)
or more verbose but also more economical:
>>> out = np.empty(2*(inp.size,), inp.dtype)
>>> out[...] = inp.ravel()
>>> np.einsum('ii->i', out)[...]^=1
>>> out = out.reshape(-1, *inp.shape)
I'd like to turn an open mesh returned by the numpy ix_ routine to a list of coordinates
eg, for:
In[1]: m = np.ix_([0, 2, 4], [1, 3])
In[2]: m
Out[2]:
(array([[0],
[2],
[4]]), array([[1, 3]]))
What I would like is:
([0, 1], [0, 3], [2, 1], [2, 3], [4, 1], [4, 3])
I'm pretty sure I could hack it together with some iterating, unpacking and zipping, but I'm sure there must be a smart numpy way of achieving this...
Approach #1 Use np.meshgrid and then stack -
r,c = np.meshgrid(*m)
out = np.column_stack((r.ravel('F'), c.ravel('F') ))
Approach #2 Alternatively, with np.array() and then transposing, reshaping -
np.array(np.meshgrid(*m)).T.reshape(-1,len(m))
For a generic case with for generic number of arrays used within np.ix_, here are the modifications needed -
p = np.r_[2:0:-1,3:len(m)+1,0]
out = np.array(np.meshgrid(*m)).transpose(p).reshape(-1,len(m))
Sample runs -
Two arrays case :
In [376]: m = np.ix_([0, 2, 4], [1, 3])
In [377]: p = np.r_[2:0:-1,3:len(m)+1,0]
In [378]: np.array(np.meshgrid(*m)).transpose(p).reshape(-1,len(m))
Out[378]:
array([[0, 1],
[0, 3],
[2, 1],
[2, 3],
[4, 1],
[4, 3]])
Three arrays case :
In [379]: m = np.ix_([0, 2, 4], [1, 3],[6,5,9])
In [380]: p = np.r_[2:0:-1,3:len(m)+1,0]
In [381]: np.array(np.meshgrid(*m)).transpose(p).reshape(-1,len(m))
Out[381]:
array([[0, 1, 6],
[0, 1, 5],
[0, 1, 9],
[0, 3, 6],
[0, 3, 5],
[0, 3, 9],
[2, 1, 6],
[2, 1, 5],
[2, 1, 9],
[2, 3, 6],
[2, 3, 5],
[2, 3, 9],
[4, 1, 6],
[4, 1, 5],
[4, 1, 9],
[4, 3, 6],
[4, 3, 5],
[4, 3, 9]])