Delete specific Values of an Array: Python - python

I have an array of the shape (1179648, 909).
The problem is that some rows are filled with 0's only. I am checking for this as follows:
for i in range(spectra1Only.shape[0]):
for j in range(spectra1Only.shape[1]):
if spectra1Only[i,j] == 0:
I now want to remove the whole row of [i] if there is any 0 appearing to get a smaller amount of only the data needed.
My question is: what would be the best method to do so? Remove? Del? numpy.delete? Or any other method?

You can use Boolean indexing with np.any along axis=1:
spectra1Only = spectra1Only[~(spectra1Only == 0).any(1)]
Here's a demonstration:
A = np.random.randint(0, 9, (5, 5))
print(A)
[[5 0 3 3 7]
[3 5 2 4 7]
[6 8 8 1 6]
[7 7 8 1 5]
[8 4 3 0 3]]
print(A[~(A == 0).any(1)])
[[3 5 2 4 7]
[6 8 8 1 6]
[7 7 8 1 5]]

Related

How to derive the following pattern with Python

How can I make the following pattern with Python, I thought about everything, but I didn't get anywhere
Problem solved, thanks to all contributors
Why negativity?
Well, if stackoverflow is not for asking questions, then what is it for???
The displayed numbers are always the maximum of the row number and column number they appear at.
So, to print that pattern, you could do something line this:
def solve(n):
for row in range(1, n + 1):
for col in range(1, n + 1):
print(max(row, col), end=" ")
print("\n")
solve(5)
As you posted an image, it is not clear whether there should be empty lines between the lines with numbers, and whether at the end it is fine to have trailing newline characters or not.
Also check whether there are requirements as to how the pattern should look when the size of the matrix is more than 9.
But it should not be hard to adapt the code accordingly.
Here's another approach:
numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers)):
for j in range(i):
numbers[j] += 1
print(*numbers)
Output:
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
import numpy as np #Just to format as matrix when printing
a=[[max(r,c) for r in range(1,6)] for c in range(1,6)]
print(np.array(a))
>>> [[1 2 3 4 5]
>>> [2 2 3 4 5]
>>> [3 3 3 4 5]
>>> [4 4 4 4 5]
>>> [5 5 5 5 5]]

Compute sum of unique values in Numpy Array by indices

I have a task to compute sum efficiently and beautifully.
I have two array
dst = [[1 2 3 4 5]
[2 3 4 5 6]
[1 1 2 2 3]
[7 8 9 9 3]]
and
ids = [[1 1 2 1 3]
[2 2 1 1 3]
[3 3 2 1 1]
[2 2 1 3 3]
[1 2 3 2 1]]
For each row in dst I need to compute sum for unique elements in ids and return max of sum and number of index.
Example for first row: I have 3 unique number in ids in first row [1,2,3].
indices for 1 = [0,1,3] for 2 = [2] for 3 = [4]
For 1: sum is sum of dst[0][0] + dst[0][1] + dst[0][3] = 1 + 2 + 4 = 7.
For 2: sum is dst[0][2] = 3
For 3: sum is dst[0][4] = 5.
max(sum) = 7
number = 3
Total: [3,7] - for first row
I have no idea how to do it with using of Numpy function efficiently and easy. I did it with classic python, but that solution works too slow.
You can try to get the unique indices like this:
indices = [np.unique(row) for row in ids]
and then calculate the sums:
sums = [np.sum(dst[i][indices[i]]) for i in range(len(dst))]

An efficient way to concatenate rows of a 2-dim array according to a given list of pairs of indexes

Suppose I have a 2 dimensional array with a very large number of rows, and a list of pairs of indexes of that array. I want to create a new 2 dim array, whose rows are concatenations of the rows of the original array, made according to the list of pairs of indexes. For example:
a =
1 2 3
4 5 6
7 8 9
0 0 0
indexes = [[0,0], [0,1], [2,3]]
the returned array should be:
1 2 3 1 2 3
1 2 3 4 5 6
7 8 9 0 0 0
Obviously I can iterate the list of indexes, but my question is whether there is a more efficient way of doing this. I should say that the list of indexes is also very large.
First convert indexes to a Numpy array:
ind = np.array(indexes)
Then generate your result as:
result = np.concatenate([a[ind[:,0]], a[ind[:,1]]], axis=1)
The result is:
array([[1, 2, 3, 1, 2, 3],
[1, 2, 3, 4, 5, 6],
[7, 8, 9, 0, 0, 0]])
Another possible formula (with the same result):
result = np.concatenate([ a[ind[:,i]] for i in range(ind.shape[1]) ], axis=1)
You can do this in one line using NumPy as:
a = np.arange(12).reshape(4, 3)
print(a)
b = [[0, 0], [1, 1], [2, 3]]
b = np.array(b)
print(b)
c = a[b.reshape(-1)].reshape(-1, a.shape[1]*b.shape[1])
print(c)
'''
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
[[0 0]
[1 1]
[2 3]]
[[ 0 1 2 0 1 2]
[ 3 4 5 3 4 5]
[ 6 7 8 9 10 11]]
'''
You can use horizontal stacking np.hstack:
c = np.array(indexes)
np.hstack((a[c[:,0]],a[c[:,1]]))
output:
[[1 2 3 1 2 3]
[1 2 3 4 5 6]
[7 8 9 0 0 0]]

(Inverse-) Sorting 2d numpy array column-wise

The following code sorts an 2d numpy array column-wise forth and back
import numpy as np
#Column-wise sort and inverse sort of image (2d array)
nrows = 10
ncols = 5
a = np.random.randint(nrows, size=(nrows, ncols))
a_sorted = np.sort(a, axis=0)
ori_indices = np.zeros_like(a)
for c in range(ncols):
ori_indices[:,c] = np.argsort(np.argsort(a[:,c]))
#Do some work on sorted array, like e.g row-wise filtering
#After processing sorted array, move it back to original order
a_backsorted = np.zeros_like(a)
for c in range(ncols):
a_backsorted[:,c] = a_sorted[:,c][ori_indices[:,c]]
print (a); print ()
print (a_backsorted); print ()
print (a_sorted); print ()
The code work as is but I guess there is a more efficient implementation without for loop (using fancy indexing)
You can try a_sorted[::-1] to reverse the array
print (a_sorted); print ()
print (a_sorted[::-1])
[[0 0 0 2 0]
[2 0 0 2 2]
[4 0 2 6 4]
[4 2 3 7 5]
[4 4 4 7 6]
[5 5 4 8 7]
[6 5 4 8 7]
[7 6 8 9 8]
[8 7 9 9 9]
[8 8 9 9 9]]
[[8 8 9 9 9]
[8 7 9 9 9]
[7 6 8 9 8]
[6 5 4 8 7]
[5 5 4 8 7]
[4 4 4 7 6]
[4 2 3 7 5]
[4 0 2 6 4]
[2 0 0 2 2]
[0 0 0 2 0]]
#Column-wise sort and inverse sort of image (2d array)
import numpy as np
#Define random array and sort it
nrows = 10
ncols = 5
a = np.random.randint(nrows, size=(nrows, ncols))
a_sorted = np.sort(a, axis=0)
#Save original order of columns
ori_indices = np.argsort(np.argsort(a, axis=0), axis=0)
#Do some work on sorted array, like e.g row-wise filtering.
#....
#After processing sorted array, move it back to original order:
c=np.array([[i] for i in range(ncols)]).T
a_backsorted = a_sorted[ori_indices, c]
#Check results
print (a); print ()
print (a_backsorted); print ()
print (a_sorted); print ()
import numpy as np
nrows = 10; ncols = 5
a = np.random.randint(nrows, size=(nrows, ncols))
a_sorted = np.sort(a, axis=0)
a_backsorted = np.zeros_like(a)
c = np.array([[i] for i in range(ncols)]).T
a_backsorted[np.argsort(a, axis=0), c] = a_sorted
The reverting of the column-wise sorting is done by inserting the values of the sorted array at the argsorted positions in the backsorted array. Since this is done columnwise, the argsorted positions are paired with the columns represented in the c array

Python numpy: reshape list into repeating 2D array

I'm new to python and I have a question about numpy.reshape. I currently have 2 lists of values like this:
x = [0,1,2,3]
y = [4,5,6,7]
And I want them to be in separate 2D arrays, where each item is repeated for the length of the original lists, like this:
xx = [[0,0,0,0]
[1,1,1,1]
[2,2,2,2]
[3,3,3,3]]
yy = [[4,5,6,7]
[4,5,6,7]
[4,5,6,7]
[4,5,6,7]]
Is there a way to do this with numpy.reshape, or is there a better method I could use? I would very much appreciate a detailed explanation. Thanks!
numpy.meshgrid will do this for you.
N.B. From your requested output, it looks like you want ij indexing, not the default xy
from numpy import meshgrid
x = [0,1,2,3]
y = [4,5,6,7]
xx,yy=meshgrid(x,y,indexing='ij')
print xx
>>> [[0 0 0 0]
[1 1 1 1]
[2 2 2 2]
[3 3 3 3]]
print yy
>>> [[4 5 6 7]
[4 5 6 7]
[4 5 6 7]
[4 5 6 7]]
For reference, here's xy indexing
xx,yy=meshgrid(x,y,indexing='xy')
print xx
>>> [[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]]
print yy
>>> [[4 4 4 4]
[5 5 5 5]
[6 6 6 6]
[7 7 7 7]]

Categories