I have a [2x2x2] numpy array a and want to expand it to [4x4x4] like b. The premise is to expand the values as well. It´s supposed to look something like this:
a = array([[[1, 2],
[-2, -1]],
[[3, -4],
[4, -3]]])
b = array([[[1, 1, 2, 2],
[1, 1, 2, 2],
[-2, -2, -1, -1],
[-2, -2, -1, -1]],
[[1, 1, 2, 2],
[1, 1, 2, 2],
[-2, -2, -1, -1],
[-2, -2, -1, -1]],
[[3, 3, -4, -4],
[3, 3, -4, -4],
[4, 4, -3, -3],
[4, 4, -3, -3]],
[[3, 3, -4, -4],
[3, 3, -4, -4],
[4, 4, -3, -3],
[4, 4, -3, -3]]])
Loosely said each value of a expands into a [2x2x2] of the same value.
My current attempt is just hard coded.
b = np.zeros(shape=(4, 4, 4), dtype='int')
b[0:2, 0:2, 0:2] = a[0, 0, 0]
b[0:2, 0:2, 2:] = a[0, 0, 1]
b[0:2, 2:, 2:] = a[0, 1, 1]
b[0:2, 2:, 0:2] = a[0, 1, 0]
b[2:, 0:2, 0:2] = a[1, 0, 0]
b[2:, 0:2, 2:] = a[1, 0, 1]
b[2:, 2:, 2:] = a[1, 1, 1]
b[2:, 2:, 0:2] = a[1, 1, 0]
This should definitely be easier. Thanks.
b = np.insert(a, slice(0,2), a, 2)
b = np.insert(b, slice(0,2), b, 1)
b = np.insert(b, slice(0,2), b, 0)
Result:
array([[[ 1, 1, 2, 2],
[ 1, 1, 2, 2],
[-2, -2, -1, -1],
[-2, -2, -1, -1]],
[[ 1, 1, 2, 2],
[ 1, 1, 2, 2],
[-2, -2, -1, -1],
[-2, -2, -1, -1]],
[[ 3, 3, -4, -4],
[ 3, 3, -4, -4],
[ 4, 4, -3, -3],
[ 4, 4, -3, -3]],
[[ 3, 3, -4, -4],
[ 3, 3, -4, -4],
[ 4, 4, -3, -3],
[ 4, 4, -3, -3]]])
Or, if it's OK to overwrite a, simply:
for axis in range(3):
a = np.insert(a, slice(0,2), a, axis)
Related
>>> b
tensor([[ 6, 7, 12, 7, 8],
[ 0, 1, 6, 1, 2],
[ 0, 1, 6, 1, 2],
[ 2, 3, 8, 3, 4],
[ 2, 3, 8, 3, 4],
[ 2, 3, 8, 3, 4],
[10, 11, 16, 11, 12],
[-1, 0, 5, 0, 1],
[-2, -1, 4, -1, 0],
[ 2, 3, 8, 3, 4],
[ 1, 2, 7, 2, 3],
[ 1, 2, 7, 2, 3],
[ 2, 3, 8, 3, 4],
[ 5, 6, 11, 6, 7],
[-2, -1, 4, -1, 0],
[-3, -2, 3, -2, -1],
[-5, -4, 1, -4, -3],
[ 1, 2, 7, 2, 3],
[12, 13, 18, 13, 14],
[-3, -2, 3, -2, -1],
[ 2, 3, 8, 3, 4],
[ 3, 4, 9, 4, 5],
[10, 11, 16, 11, 12],
[-6, -5, 0, -5, -4],
[ 9, 10, 15, 10, 11],
[12, 13, 18, 13, 14],
[-3, -2, 3, -2, -1],
[-2, -1, 4, -1, 0],
[-4, -3, 2, -3, -2],
[-1, 0, 5, 0, 1],
[ 2, 3, 8, 3, 4],
[ 4, 5, 10, 5, 6],
[-1, 0, 5, 0, 1],
[ 5, 6, 11, 6, 7],
[ 7, 8, 13, 8, 9],
[ 3, 4, 9, 4, 5],
[ 2, 3, 8, 3, 4],
[ 4, 5, 10, 5, 6],
[-4, -3, 2, -3, -2],
[ 2, 3, 8, 3, 4],
[-1, 0, 5, 0, 1],
[ 2, 3, 8, 3, 4],
[ 4, 5, 10, 5, 6],
[ 9, 10, 15, 10, 11],
[-1, 0, 5, 0, 1],
[-4, -3, 2, -3, -2],
[ 0, 1, 6, 1, 2],
[ 4, 5, 10, 5, 6],
[ 6, 7, 12, 7, 8],
[-2, -1, 4, -1, 0]])
>>> torch.mode(b, 0)
torch.return_types.mode(
values=tensor([2, 3, 8, 3, 4]),
indices=tensor([20, 20, 20, 20, 20]))
i don't know why indeces is all equal to 20
the details of torch.mode description as below
https://pytorch.org/docs/stable/generated/torch.mode.html#torch.mode
torch.mode(input, dim=- 1, keepdim=False, *, out=None)
Returns a namedtuple (values, indices) where values is the mode value of each row of the input tensor in the given dimension dim, i.e. a value which appears most often in that row, and indices is the index location of each mode value found.
By default, dim is the last dimension of the input tensor.
If keepdim is True, the output tensors are of the same size as input except in the dimension dim where they are of size 1. Otherwise, dim is squeezed (see torch.squeeze()), resulting in the output tensors having 1 fewer dimension than input.
It is because of the way the tensor b is. The row [2, 3, 8, 3, 4] is repeated a lot, so in each column the modes are respectively [2, 3, 8, 3, 4] and more importantly, the mode indices will be equal precisely because the modes occur together; if you look at the row with index 20 (i.e., the 21st row), it is exactly [2, 3, 8, 3, 4].
I am assuming that you constructed b similar to the example in torch.mode which I believe is a poor choice for an example as it leads to confusion like the one you are having.
Instead, consider the following:
>>> b = torch.randint(4, (5, 7))
>>> b
tensor([[0, 0, 0, 2, 0, 0, 2],
[0, 3, 0, 0, 2, 0, 1],
[2, 2, 2, 0, 0, 0, 3],
[2, 2, 3, 0, 1, 1, 0],
[1, 1, 0, 0, 2, 0, 2]])
>>> torch.mode(b, 0)
torch.return_types.mode(
values=tensor([0, 2, 0, 0, 0, 0, 2]),
indices=tensor([1, 3, 4, 4, 2, 4, 4]))
In the above, b has different modes in each column which are respectively [0, 2, 0, 0, 0, 0, 2] and the indices returned by torch.mode are [1, 3, 4, 4, 2, 4, 4]. This makes sense because, for example, in the first column, 0 is the most common element and there is a 0 at index 1. Similarly, in the second column, 2 is the most common element and there is a 2 at index 3. This is true for all columns. If you want the modes of the rows instead, you would do torch.mode(b, 1).
I have the indices of a 2D array. I want to partition the indices such that the corresponding entries form blocks (block size is given as input m and n).
For example, if the indices are as given below
(array([0, 0, 0, 0, 1, 1, 1, 1, 6, 6, 6, 6, 7, 7, 7, 7 ]), array([0, 1, 7, 8, 0,1,7,8, 0,1,7,8, 0, 1, 7, 8]))
for the original matrix (from which the indices are generated)
array([[3, 4, 2, 0, 1, 1, 0, 2, 4],
[1, 3, 2, 0, 0, 1, 0, 4, 0],
[1, 0, 0, 1, 1, 0, 1, 1, 3],
[0, 0, 0, 3, 3, 0, 4, 0, 4],
[4, 3, 4, 2, 1, 1, 0, 0, 4],
[0, 1, 0, 4, 4, 2, 2, 2, 1],
[2, 4, 0, 1, 1, 0, 0, 2, 1],
[0, 4, 1, 3, 3, 2, 3, 2, 4]])
and if the block size is (2,2), then the blocks should be
[[3, 4],
[1, 3]]
[[2, 4]
[4, 0]]
[[2, 4]
[0, 4]]
[[2, 1]
[2, 4]]
Any help to do it efficiently?
Does this help? A is your matrix.
row_size = 2
col_size = 3
for i in range(A.shape[0] // row_size):
for j in range(A.shape[1] // col_size):
print(A[row_size*i:row_size*i + row_size, col_size*j:col_size*j + col_size])
I have this:
array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]])
And I would like to reshape my array like this:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[2, 2, 3, 3],
[2, 2, 3, 3]])
How do I do it using python numpy?
You can just split and concatenate:
a = np.array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]])
cols = a.shape[1] // 2
np.concatenate((a[:,:cols], a[:,cols:]))
#[[0 0 1 1]
# [0 0 1 1]
# [2 2 3 3]
# [2 2 3 3]]
You can simply swap rows after reshaping it.
a= np.array([[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]]).reshape(4,4)
a[[1,2]] = a[[2,1]]
Output:
array([[0, 0, 1, 1],
[0, 0, 1, 1],
[2, 2, 3, 3],
[2, 2, 3, 3]])
I want to ask how numpy remove columns in batch by list.
The value in the list corresponds to the batch is different from each other.
I know this problem can use the for loop to solve, but it is too slow ...
Can anyone give me some idea to speed up?
array (batch size = 3):
[[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]
remove index in the list (batch size = 3)
[[2, 3, 4], [1, 2, 6], [0, 1, 5]]
output:
[[0, 1, 5, 6], [0, 3, 4, 5], [2, 3, 4, 6]]
Assuming the array is 2d, and the indexing removes equal number of elements per row, we can remove items with a boolean mask:
In [289]: arr = np.array([[0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6], [0, 1, 2, 3, 4, 5, 6]]
...: )
In [290]: idx = np.array([[2, 3, 4], [1, 2, 6], [0, 1, 5]])
In [291]: mask = np.ones_like(arr, dtype=bool)
In [292]: mask[np.arange(3)[:,None], idx] = False
In [293]: arr[mask]
Out[293]: array([0, 1, 5, 6, 0, 3, 4, 5, 2, 3, 4, 6])
In [294]: arr[mask].reshape(3,-1)
Out[294]:
array([[0, 1, 5, 6],
[0, 3, 4, 5],
[2, 3, 4, 6]])
I know I can do np.subtract.outer(x, x). If x has shape (n,), then I end up with an array with shape (n, n). However, I have an x with shape (n, 3). I want to output something with shape (n, n, 3). How do I do this? Maybe np.einsum?
You can use broadcasting after extending the dimensions with None/np.newaxis to form a 3D array version of x and subtracting the original 2D array version from it, like so -
x[:, np.newaxis, :] - x
Sample run -
In [6]: x
Out[6]:
array([[6, 5, 3],
[4, 3, 5],
[0, 6, 7],
[8, 4, 1]])
In [7]: x[:,None,:] - x
Out[7]:
array([[[ 0, 0, 0],
[ 2, 2, -2],
[ 6, -1, -4],
[-2, 1, 2]],
[[-2, -2, 2],
[ 0, 0, 0],
[ 4, -3, -2],
[-4, -1, 4]],
[[-6, 1, 4],
[-4, 3, 2],
[ 0, 0, 0],
[-8, 2, 6]],
[[ 2, -1, -2],
[ 4, 1, -4],
[ 8, -2, -6],
[ 0, 0, 0]]])