I have a big array of numbers which contain the data for the flux of a star. I want to remove all the data points below the value of 1. I used the code fluxbelow1=[i for i, j in enumerate(z) if j<1] to get the index for all the data points. I now want to remove these points from the original array and create a smaller array. How would I do that?
Numpy is particularly good at this.
fluxabove1 = z[z >= 1]
The "z >= 1" creates an array of booleans where the value is greater or equal to 1. We then use that to index into z and choose only those elements.
Related
I have a number of data files, each containing a large amount of data points.
After loading the file with numpy, I get a numpy array:
f=np.loadtxt("...-1.txt")
How do I randomly select a length of x, but the order of numbers should not be changed?
For example:
f = [1,5,3,7,4,8]
if I wanted to select a random length of 3 data points, the output should be:
1,5,3, or
3,7,4, or
5,3,7, etc.
Pure logic will get you there.
For a list f and a max length x, the valid starting points of your random slices are limited to 0, len(f)-x:
0 1 2 3
f = [1,5,3,7,4,8]
So all valid starting point can be selected with random.randrange(len(f)-x+1) (where the +1 is because randrange works like range).
Store the random starting point into a variable start and slice your array with [start:start+x], or be creative and use another slice after the first:
result = f[random.randrange(len(f)-x+1):][:3]
Building on usr2564301's answer you can take out only the elements you need in 1 go using a range so you avoid building a potentially very large intermediate array:
result = f[range(random.randrange(len(f)-x+1), x)]
A range also avoids that you build large index arrays when your length x becomes larger.
So I have an image which I imported to python. The imread command basically gives me an array X,Y,Z where X and Y are the coordinates of the pixels and Z (which has four dimensions) gives me the RGB values at a given point (X,Y).
import matplotlib.image as img
import numpy as np
RawImg = img.imread('tek0000.bmp','RGB')
CrpImg = RawImg[14:208,12:256,:]
x_values = []
y_values = []
for row in CrpImg:
for cell in row:
print(np.nonzero)
if (cell == [136,136,0,255]).all:
My goal is to analyze the exact points in the array where the RGB configuration is [136,136,0,255]. These points are greenish-yellow. I want to add the X and Y values to lists or arrays so I can plot them.
In order to achieve this, I iterate over every point X and Y (row and column) of the array, and analyze the Z values. What I need is the coordinate (X,Y) of the cell in the for loop.
Basically, if the color in the point (X,Y) of the image is yellow, add that point (X,Y) to the list.
Surprisingly I cannot find pretty much anything online for what I think, is a relatively simple thing. I realize that I can interate using the following:
for i in range len(X axis) something like that, but I want to know if it is possible this way.
Not completely sure this is what you're looking for, but I think you want to get the index from inside the loop. The main ways to do this would be
loop using the index, e.g. for i in range(0,255): and then index into the array
iterate using enumerate, which returns an index as well as value in a collection
use the index method
I think the easiest option for you will be the index method.
for row in CrpImg:
for cell in row:
print(np.nonzero)
if (cell == [136,136,0,255]).all:
print(CrpImg.index(row), row.index(cell))
Note that this is going to give you the index inside your crop rather than the full image. You can either adjust (by adding 14 and 12), or you can iterate over the full image.
If you use enumerate from the standard library, you get access to a tuple containing a count and your values. The count starts at 0 by default
for row in CrpImg
becomes
for num, row in enumerate(CrpImg):
print(num)
Try using numpy.where:
indices = numpy.where(my_array == [136,136,0,255])
Is there any neat way to check is numpy array surrounded by zeros.
Example:
[[0,0,0,0],
[0,1,2,0],
[0,0,0,0]]
I know I can iterate it element wise to find out but I wonder is there any nice trick we can use here. The numpy array is of floats, n x m of arbitrary size.
Any ideas are welcome.
You can use numpy.any() to test if there is any non-zero element in numpy array.
Now, to test if a 2D array is surrounded by zeroes, you can get first and last columns as well as first and last rows and test if any of those contains a non-zero number.
def zero_surrounded(array):
return not (array[0,:].any() or array[-1,:].any() or array[:,0].any() or array[:,-1].any())
We can check this by constructing two submatrices:
A[[0,-1]] the first and the last row, including the first and last column; and
A[1:-1,[0,-1]] the first and last column, excluding the first and last row.
All the values of these matrices should be equal to zero, so we can use:
if np.all(A[[0,-1]] == 0) and np.all(A[1:-1,[0,-1]] == 0):
# ...
pass
This works for an arbitrary 2d-array, but not for arrays with arbitrary depth. We can however use a trick for that as well.
For an arbitrary matrix, we can use:
def surrounded_zero_dim(a):
n = a.ndim
sel = ([0,-1],)
sli = (slice(1,-1),)
return all(np.all(a[sli*i+sel] == 0) for i in range(n))
Using the slice is strictly speaking not necessary, but it prevents checking certain values twice.
Not the fastest, but perhaps the shortest (and hence a "neat") way of doing it:
surrounded = np.sum(a[1:-1, 1:-1]**2) == np.sum(a**2)
print(surrounded) # True
Here, a is the array.
This compares the sum of all squared elements to the sum of all squared elements except for those on the boundary. If we left out the squaring, cases where positive and negative boundary values add up to zero would produce the wrong answer.
I have a 2D array (image) in which I want to replace array values greater than some threshold with a random number in some range. My attempt was to use numpy.random.uniform, as so
Z[Z > some_value] = uniform(lower_limit,upper_limit)
However I've found that this replaces all values above the threshold with the same random value. I would like to replace all array values above the threshold with a different random value each.
I think this would require some interation over the entire array for which I would need to generate a random value if the condition is met. How would I do this?
You are correct that iteration would be the correct way to go. Let's do a list comprehension.
[uniform(lower_limit, upper_limit) if i > some_value else i
for i in Z]
Let's step through it. Take an individual value. If it is greater than the threshold, use a randomly generated one, otherwise the original value.
uniform(lower_limit, upper_limit) if i > some_value else i
Repeat this for every element in Z
for i in Z
For a 2D array, nest multiple comprehensions. Imagine that the above solution was to hit everything in one row and then repeat it for every row.
[[uniform(lower_limit, upper_limit) if i > some_value else i
for i in row]
for row in Z]
Check the third argument to uniform. Using size=N will yield an array of random values with length N. Thus
z[z>some_value] = np.random.uniform(lower, upper, len(z>some_value))
will do what you want.
Let's say I have two vectors of size n containing coordinates (point1 and point2), and some large Numpy array with n dimensions (len(array.shape) == 3).
Now, all values of point1 are smaller than point2 and I want to extract the subarray contained between point1 and point2. If I knew the number of dimensions n beforehand (e.g. n=3), I would access it like this:
array[point1[0]:point2[0], point1[1]:point2[1], point1[2]:point2[2]]
I was wondering if there was a clean pythonic way to do this in Numpy that would work for any number of dimensions?
Thanks!
array[map(slice,point1,point2)]
The index of A[0:2,0:2] is the same as (slice(0,2), slice(0,2)) which is a tuple of slice.