How replace values from one numpy array by other array with indices - python

I have two arrays and one list with indices
Array source (array 01):
x = np.array([[1,2,3], [4,5,6], [7,8,9]])
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Array with new values (array 02):
y = np.array([11, 22, 33])
array([11, 22, 33])
and a list with indices
a = [1,2,1]
[1, 2, 1]
I need to replace the values of array 02 in array 01 based on indices
The return expected:
array([[1, 11, 3],
[4, 5, 22],
[7, 33, 9]])
How to do this without loop?
Thanks in advance.

Try advanced indexing:
x[np.arange(len(x)), a] = y
I found also this tutorial easier for me than official documentation.

Related

Python numpy 2D array sum over certain indices

There is a 2-d array like this:
img = [
[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
[[2, 2, 2], [3, 2, 3], [6, 7, 6]],
[[9, 8, 1], [9, 8, 3], [9, 8, 5]]
]
And i just want to get the sum of certain indices which are like this:
indices = [[0, 0], [0, 1]] # which means img[0][0] and img[0][1]
# means here is represents
There was a similar ask about 1-d array in stackoverflow in this link, but it got a error when I tried to use print(img[indices]). Because I want to make it clear that the element of img are those which indicates by indices, and then get the mean sum of it.
Expected output
[5, 7, 9]
Use NumPy:
import numpy as np
img = np.array(img)
img[tuple(indices)].sum(axis = 0)
#array([5, 7, 9])
If the result would be [5, 7, 9] which is sum over the column of the list. Then easy:
img = np.asarray(img)
indices = [[0, 0], [0, 1]]
img[(indices)].sum(axis = 0)
Result:
array([5, 7, 9])
When you supply a fancy index, each element of the index tuple represents a different axis. The shape of the index arrays broadcasts to the shape of the output you get.
In your case, the rows of indices.T are the indices in each axis. You can convert them into an index tuple and append slice(None), which is the programmatic equivalent of :. You can take the mean of the resulting 2D array directly:
img[tuple(indices.T) + (slice(None),)].sum(0)
Another way is to use the splat operator:
img[(*indices.T, slice(None))].sum(0)

Concatenate NumPy 2D array with column (1D array)

Suppose I have a 2D NumPy array values. I want to add new column to it. New column should be values[:, 19] but lagged by one sample (first element equals to zero). It could be returned as np.append([0], values[0:-2:1, 19]). I tried: Numpy concatenate 2D arrays with 1D array
temp = np.append([0], [values[1:-2:1, 19]])
values = np.append(dataset.values, temp[:, None], axis=1)
but I get:
ValueError: all the input array dimensions except for the concatenation axis
must match exactly
I tried using c_ too as:
temp = np.append([0], [values[1:-2:1, 19]])
values = np.c_[values, temp]
but effect is the same. How this concatenation could be made. I think problem is in temp orientation - it is treated as a row instead of column, so there is an issue with dimensions. In Octave ' (transpose operator) would do the trick. Maybe there is similiar solution in NumPy?
Anyway, thank you for you time.
Best regards,
Max
In [76]: values = np.arange(16).reshape(4,4)
In [77]: temp = np.concatenate(([0], values[1:,-1]))
In [78]: values
Out[78]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [79]: temp
Out[79]: array([ 0, 7, 11, 15])
This use of concatenate to make temp is similar to your use of append (which actually uses concatenate).
Sounds like you want to join values and temp in this way:
In [80]: np.concatenate((values, temp[:,None]),axis=1)
Out[80]:
array([[ 0, 1, 2, 3, 0],
[ 4, 5, 6, 7, 7],
[ 8, 9, 10, 11, 11],
[12, 13, 14, 15, 15]])
Again I prefer using concatenate directly.
You need to convert the 1D array to 2D as shown. You can then use vstack or hstack with reshaping to get the final array you want as shown:
a = np.array([[1, 2, 3],[4, 5, 6]])
b = np.array([[7, 8, 9]])
c = np.vstack([ele for ele in [a, b]])
print(c)
c = np.hstack([a.reshape(1,-1) for a in [a,b]]).reshape(-1,3)
print(c)
Either way, the output is:
[[1 2 3] [4 5 6] [7 8 9]]
Hope I understood the question correctly

How to split numpy array vertically from any column index

I want to split a numpy array into two subarrays where the splitting point is based on a column id, i.e., vertical split. For instance, if I generate a numpy array of shape [10,16] and I want to create two subarrays by splitting it from the column's index 11, then I should get one subarray of size [10,10] and the other one is from [10,15]. Therefore, I am following numpy.hsplit here but it seems it only does an even split (the subarrays need to be equal). I want to be able to:
Split any numpy array vertically, no matter what is the size of subarrays.
Extract both subarrays.
To simulate my request, the following is my code:
import numpy as np
C = [[1,2,3,4],[5,6,7,8],[9,10,11,12], [13,14,15,16]]
C = np.asarray(C)
C = np.hsplit(C, 3)
print(C)
As you can see, np.hsplit(C, 3) doesn't work unless the splitting generates similar subarrays. Even if I did np.hsplit(C, 2), I don't know how to extract both subarrays into separate numpy arrays.
To achieve my goals, how can I modify this code?
Use the array indexing.
C[:,:3] # All rows , columns 0 to 2
Out[29]:
array([[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11],
[13, 14, 15]])
C[:,3:] # All rows column 3 (to end in this case also 3).
Out[30]:
array([[ 4],
[ 8],
[12],
[16]])
You need to specify the indices as list:
import numpy as np
C = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
C = np.asarray(C)
C = np.hsplit(C, [3])
print(C)
Output
[array([[ 1, 2, 3],
[ 5, 6, 7],
[ 9, 10, 11],
[13, 14, 15]]), array([[ 4],
[ 8],
[12],
[16]])]

How to create a 2d numpy ndarray using two list comprehensions

I tried to create a 2D numpy ndarray using the following code:
temp = np.array([[np.mean(w2v[word]) for word in docs if word in w2v] for docs in X[:5]])
temp has a shape of (5,) instead of expected (5,x).
Also temps's data structure is like: array([list([.....],...)])
It seems that the inner list is not converted to ndarray.
Your missing np.array in there, it should be:
temp = np.array([np.array([np.mean(w2v[word]) for word in docs if word in w2v] for docs in X[:5])])
Running example:
bob
Out[70]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
tmp = np.array([np.array([x for x in Y]) for Y in bob])
tmp
Out[72]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])

Numpy Search & Slice 3D Array

I'm very new to Python & Numpy and am trying to accomplish the following:
Given, 3D Array:
arr_3d = [[[1,2,3],[4,5,6],[0,0,0],[0,0,0]],
[[3,2,1],[0,0,0],[0,0,0],[0,0,0]]
[[1,2,3],[4,5,6],[7,8,9],[0,0,0]]]
arr_3d = np.array(arr_3d)
Get the indices where [0,0,0] appears in the given 3D array.
Slice the given 3D array from where [0,0,0] appears first.
In other words, I'm trying to remove the padding (In this case: [0,0,0]) from the given 3D array.
Here is what I have tried,
arr_zero = np.zeros(3)
for index in range(0, len(arr_3d)):
rows, cols = np.where(arr_3d[index] == arr_zero)
arr_3d[index] = np.array(arr_3d[0][:rows[0]])
But doing this, I keep getting the following error:
Could not broadcast input array from shape ... into shape ...
I'm expecting something like this:
[[[1,2,3],[4,5,6]],
[[3,2,1]]
[[1,2,3],[4,5,6],[7,8,9]]]
Any help would be appreciated.
Get the first occurance of those indices with all() reduction alongwith argmax() and then slice each 2D slice off the 3D array -
In [106]: idx = (arr_3d == [0,0,0]).all(-1).argmax(-1)
# Output as list of arrays
In [107]: [a[:i] for a,i in zip(arr_3d,idx)]
Out[107]:
[array([[1, 2, 3],
[4, 5, 6]]), array([[3, 2, 1]]), array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])]
# Output as list of lists
In [108]: [a[:i].tolist() for a,i in zip(arr_3d,idx)]
Out[108]: [[[1, 2, 3], [4, 5, 6]], [[3, 2, 1]], [[1, 2, 3], [4, 5, 6], [7, 8, 9]]]

Categories