Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to slice up a numpy array with inequalities?

I've done my best to find a solution on my own but I'm just not turning up anything relevant. I've got some numpy arrays that are extracted from .tbl files (it's an astronomical table format that I'm extracting with atpy). There are about 25,000 numbers in each array, and I'm plotting them as a scatter plot with matplotlib. The y-axis values come straight from the array, the x-axis is a simple subtraction of values in two separate arrays.

That's all fine, but what I really need to do is extract the values that fall in a certain range (for example, I need the values for the y that fall between 10 and 13, and values of x between 0 and 1). And for the plot to work, of course, these values all have to match up with each other. Here's what I've got:

import numpy as np
from numpy import ndarray
import matplotlib.pyplot as plt
import matplotlib
import atpy

twomass = atpy.Table()

twomass.read('/Raw_Data/IRSA_downloads/2MASS_GCbox1.tbl')

hmag = list([twomass['h_m']])

jmag = list([twomass['j_m']])

colorjh = list([j-h for j,h in zip(jmag, hmag)])

x = []

y = []

def list_maker():
for c,h in zip(colorjh, hmag):
    if np.all(c) < 1 == True and np.all(c) > 0 == True and np.all(h) < 13 == True and np.all(h) > 10 == True:
        x.append(c)
        y.append(h)       

list_maker()

plt.scatter(x, y, c='g', s=1, alpha=0.05)

plt.xlabel('Color(J-H)', fontsize=15)           #adjust axis labels here
plt.ylabel('Magnitude (H)', fontsize=15)

plt.gca().invert_yaxis()

plt.legend(loc=2)
plt.title('CMD for Galactic Center (2MASS)', fontsize=20)
plt.grid(True)

plt.show()

I've also tried this method for slicing the data, but no luck:

colorjh = colorjh[colorjh<1]

colorjh = colorjh[colorjh>0]

I've tried lots of different things, including trying to turn these arrays into lists, and lots of different things with the formatting of the inequalities. In the process I may have gotten myself farther away from the answer, but this code at least prints the entire scatter (it fails to cut up the data like I want). Some other iterations have printed blank plots nowhere near the number range I'm looking for.

I'm new to python, and this site, so please be as explicit as you can with any tips, etc. If it's super jargony I might not be able to make good use of your suggestion. Thanks everyone.

like image 857
Teachey Avatar asked Jan 13 '23 21:01

Teachey


2 Answers

Try the following, I think it does the same as your fors and zips, but should be much faster. If something doesn't make sense, ask in the comments and I will edit:

hmag = np.array(hmag)
jmag = np.array(jmah)

colorjh = jmag - hmag
idx_c = (colorjh > 0) & (colorjh < 1) # where condition on c is met
idx_h = (hmag > 10) & (hmag < 13) # where condition on h is met
idx = idx_c & idx_h # where both conditions are met

plt.scatter(colorjh[idx], hmag[idx], c='g', s=1, alpha=0.05)
like image 193
Jaime Avatar answered Jan 19 '23 11:01

Jaime


Both conditions can be done at once:

hmag = np.array(hmag)
jmag = np.array(jmah)
colorjh = jmag - hmag

idx = ((colorjh > 0) & (colorjh < 1) & (hmag > 10) & (hmag < 13)).nonzero()[0]

plt.scatter(colorjh[idx], hmag[idx], c='g', s=1, alpha=0.05)

That .nonzero()[0] makes it a list of indices, rather than a 'mask' with True and False values, this could be more efficient if we are talking about very long lists.

like image 22
Marcel Avatar answered Jan 19 '23 11:01

Marcel