How to modify every third element in matrix? - python

I had to make a matrix using numpy.array method. How can I now update every third element of my matrix? I have made a for loop for the problem but that is not the optimal solution. Is there a way to avoid loops? For example if I have this matrix:
matrix = np.array([[1,2,3,4],
[5,6,7,8],
[4,7,6,9]])
is there a way to add 1 to every third element and get this matrix:
[[2,2,3,5],[5,6,8,8],[4,8,6,9]]

Solution:
matrix = np.ascontiguousarray(matrix)
matrix.ravel()[::3] += 1
Why does the ascontiguousarray is needed? Because matrix may not be c-contiguous (for example matrix may have fortran-order - column major). It that case ravel returns a copy instead of a view so a simple inplace operation matrix.ravel()[::3] += 1 will not work as expected.
Example 1
import numpy as np
arr = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[4, 7, 6, 9]])
arr.ravel()[::3] += 1
print(arr)
Works as expected:
[[2 2 3 5]
[5 6 8 8]
[4 8 6 9]]
Example 2
But with fortran-order
import numpy as np
arr = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[4, 7, 6, 9]])
arr = np.asfortranarray(arr)
arr.ravel()[::3] += 1
print(arr)
produces:
[[1 2 3 4]
[5 6 7 8]
[4 7 6 9]]
Example 3
Will work as expected in both cases
import numpy as np
arr = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8],
[4, 7, 6, 9]])
# arr = np.asfortranarray(arr)
arr = np.ascontiguousarray(arr)
arr.ravel()[::3] += 1
print(arr)

Related

Find the row index number of an array in a 2D numpy array

If I have a 2D numpy array A:
[[6 9 6]
[1 1 2]
[8 7 3]]
And I have access to array [1 1 2]. Clearly, [1 1 2] belongs to index 1 of array A. But how do I do this?
Access the second row using the following operator:
import numpy as np
a = np.array([[6, 9, 6],
[1, 1, 2],
[8, 7, 3]])
row = [1, 1, 2]
i = np.where(np.all(a==row, axis=1))
print(i[0][0])
np.where will return a tuple of indices (lists), which is why you need to use the operators [0][0] consecutively in order to obtain an int.
One option:
a = np.array([[6, 9, 6],
[1, 1, 2],
[8, 7, 3]])
b = np.array([1, 1, 2])
np.nonzero((a == b).all(1))[0]
output: [1]
arr1 = [[6,9,6],[1,1,2],[8,7,3]]
ind = arr1.index([1,1,2])
Output:
ind = 1
EDIT for 2D np.array:
arr1 = np.array([[6,9,6],[1,1,2],[8,7,3]])
ind = [l for l in range(len(arr1)) if (arr1[l,:] == np.array([1,1,2])).all()]
import numpy as np
a = np.array([[6, 9, 6],
[1, 1, 2],
[8, 7, 3]])
b = np.array([1, 1, 2])
[x for x,y in enumerate(a) if (y==b).all()] # here enumerate will keep the track of index
#output
[1]

Can not flatten a numpy array

Why isn't flatten working? I have looked at example code and I am doing exactly what they are doing in the example. I've even copied their code and ran it but the array still doesn't come out as a flattened array.
I don't know if it matters but I am running Python 3.7.4.
code:
import numpy as np
array1 = np.array([[1, 2, 3, 2, 5, 8], [9, 5, 1, 7, 5, 3]])
array1.flatten()
print(array1)
output:
[[1 2 3 2 5 8]
[9 5 1 7 5 3]]
desired output:
[1 2 3 2 5 8 9 5 1 7 5 3]
array1.flatten() returns the flattened array but does not change in place. Try equating it back should work.
Code:
import numpy as np
array1 = np.array([[1, 2, 3, 2, 5, 8], [9, 5, 1, 7, 5, 3]])
array1 = array1.flatten()
print(array1)
You have to assign the array1.flatten() to a variable, so something like this could work array2 = array1.flatten().

How to remove a column from a numpy array if the column has a specified element? (Python)

For example, I have a 2D Array with dimensions 3 x 3.
[1 2 7
4 5 6
7 8 9]
And I want to remove all columns which contain 7 - so first and third, outputting a 3 x 1 matrix of:
[2
5
8]
How do I go about doing this in python? I want to apply it to a large matrix of n x n dimensions.
Thank You!
#Creating array
x = np.array([[1, 2, 7],[4,5, 6],[7,8,9]])
x
Out[]:
array([[1, 2, 7],
[4, 5, 6],
[7, 8, 9]])
#Deletion
a = np.delete(x,np.where(x ==7),axis=1)
a
Out[]:
array([[2],
[5],
[8]])
numpy can help you do this!
import numpy as np
a = np.array([1, 2, 7, 4, 5, 6, 7, 8, 9]).reshape((3, 3))
b = np.array([col for col in a.T if 7 not in col]).T
print(b)
If you don't actually want to delete parts of the original matrix, you can just use boolean indexing:
a
Out[]:
array([[1, 2, 7],
[4, 5, 6],
[7, 8, 9]])
a[:, ~np.any(a == 7, axis = 1)]
Out[]:
array([[2],
[5],
[8]])
you can use argwhere for column index and then delete.
import numpy
a = numpy.array([[5, 2, 4],[1, 7, 3],[1, 2, 7]])
index = numpy.argwhere(a==7)
y = numpy.delete(a, index, axis=1)
print(y)
A = np.array([[1,2,7],[4,5,6],[7,8,9]])
for i in range(0,3):
... B=A[:,i]
... if(7 in B):
... A=np.delete(A,i,1)

How to append a "label" to a numpy array

I have a numpy array created such as:
x = np.array([[1,2,3,4],[5,6,7,8]])
y = np.asarray([x])
which prints out
x=[[1 2 3 4]
[5 6 7 8]]
y=[[[1 2 3 4]
[5 6 7 8]]]
What I would like is an array such as
[0 [[1 2 3 4]
[5 6 7 8]]]
What's the easiest way to go about this?
Thanks!
To do what you're asking, just use the phrase
labeledArray = [0, x]
This way, you will get a standard list with 0 as the first element and a Numpy array as the second element.
However, in practice, you are probably trying to label for the purpose of later recall. In that case, I'd recommend you use a dictionary, as it is less confusing to keep track of:
myArrays = {}
myArrays[0] = x
Which can be used as follows:
>>> myArrays
{0: array([[1, 2, 3, 4],
[5, 6, 7, 8]])}
>>> myArrays[0]
array([[1, 2, 3, 4],
[5, 6, 7, 8]])

concatinate numpy matrices to get an array with dimension 3

I want to concatenate numpy matrices that have different shapes in order to get an array with dimension=3.
example :
A= [[2 1 3 4]
[2 4 0 6]
[9 5 7 4]]
B= [[7 2 8 4]
[8 6 8 6]]
and result what I need should be like that:
C=[[[2 1 3 4]
[2 4 0 6]
[9 5 7 4]]
[[7 2 8 4]
[8 6 8 6]]]
Thanks for help
If I understand your question correctly, a 3dim numpy array is probably not the way to represent your data, because there's no definitive shape.
A 3dim numpy array should have a shape of the form N1 x N2 x N3, whereas in your case each "2dim row" has a different shape.
Alternatives would be to keep your data in lists (or a list of arrays), or to use masked arrays, if that happens to be reasonable in you case.
You can only convert to a 3D np.ndarray in a useful manner if A.shape == B.shape. In that case all you need to do is e.g. C = np.array([A, B]).
import numpy as np
A = np.array([[2, 1, 3, 4],
[9, 5, 7, 4]])
B = np.array([[7, 2, 8, 4],
[8, 6, 8, 6]])
C = np.array([A, B])
print C
Because A and B have different sizes (# of rows), the best you can do make an array of shape (2,) and dtype object. Or at least that's what a simple construction gives you:
In [9]: np.array([A,B])
Out[9]:
array([array([[2, 1, 3, 4],
[2, 4, 0, 6],
[9, 5, 7, 4]]),
array([[7, 2, 8, 4],
[8, 6, 8, 6]])], dtype=object)
But constructing an array like this doesn't help much. Just use the list [A,B].
np.vstack([A,B]) produces a (5,4) array.
np.array([A[:2,:],B]) gives a (2,2,4) array. Or you could pad B so they are both (3,4).
So one way or other you need to redefine your problem.

Categories