I am trying to isolate the last column of a numpy array. However, the function needs to work for arrays of different sizes. When I put it like this:
array[:,array_length]
#array_length is a variable set to the length of one row of the array
which seems like it would work, it returns an error telling me that I can't slice with a variable, but only with an integer.
Is there a way to do this with numpy that I'm not seeing?
To access the last column of a numpy array, you can use -1
last_col = array[:, -1]
Or you can also do
array_length = len(array[0]) - 1
last_col = array[:, array_length]
Related
I have two numpy arrays - both generated from the same main array. one is generated from a slice of the main array and the other is from a where clause. the problem I am having is that when I get the indices from the where clause and apply it to the second array, I get an error: only integer scalar arrays can be converted to a scalar index. I've tried converting the array using transpose and using just the row portion of the where result, but still with the same issue.
y=np.empty([0,24])
#y array is filled with records
z[:,0]=y[:,1]
z[:,1]=y[:,2]
z[:,3]=y[:,3]
#...(total of 24 columns in y and I only use 6 in the z array)
#some data calcs from y
ar = np.array(y[:,7] - y[:,8]) #PVExport
ar = [maxamount if i > maxamount else i for i in ar]
ar = [0 if i < 0 else i for i in ar]
#where clause - get all false values in column 6. the
#here is where the error happens
naList=np.where(y[:,6]==0)
ar[naList[0]]=maxamount
z[:,4]=ar
when the above line executes - I get the error only integer scalar arrays can be converted to a scalar index.
when I try something similar by filling an array in the interactive window it seems to work.
looking to fill the 4th column of that z array with the results of some data calculations in the y array. any help is appreciated
Given an array defined below as:
a = np.arange(30).reshape((3, 10)
col_index = [[1,2,3,5], [3,4,5,7]]
row_index = [2,1]
Is it possible to index a[row_index, col_index], so I can do something like
a[row_index, col_index] =1, so then a becomes
[[0,1,2,3,4,5,6,7,8,9], [10,11,12,1,1,1,16,1,18,19], [20,1,1,1,24,1,26,27,28,29]]
So to clarify, in row 2, column 1,2,3, and 5 are set to one, and in row 1, column 3,4,5,7 is also set to 1.
Or (if you don't like typing)
a[np.c_[row_index], col_index] = 1
or even shorter but Python 2 only
a[zip(row_index), col_index] = 1
What all these solutions do is to make row and col indices broadcastable to each other. np.c_ is the column concatenation convenience object. It makes columns out of 1D objects.
zip used to do essentially the same. Only, since Python 3 it returns an iterator instead of a list and numpy can't handle those. (One could do list(zip(row_index)) but that's not short.)
I am using Python Numpy arrays (rasters converted to 2D arrays, specifically) and what I want to do is take one array that has arbitrary dummy values of -999 representing "no data" and I want to replace those values with the corresponding "real" values from a different array of the same size and shape in the correct location. I couldn't find a very similar question to this but note that I am a novice with Python and Numpy.
But what I want to do is this:
array_a =
([[0.564,-999,-999],
[0.234,-999,0.898],
[-999,0.124,0.687],
[0.478,0.786,-999]])
array_b =
([[0.324,0.254,0.204],
[0.469,0.381,0.292],
[0.550,0.453,0.349],
[0.605,0.582,0.551]])
use the values of array_b to fill in the -999 values in array_a and create a new array:
new_array_a =
([[0.564,0.254,0.204],
[0.234,0.381,0.898],
[0.550,0.124,0.687],
[0.478,0.786,0.551]])
I don't really want to change the shape or dimensions of the array because I am going to convert back out into a raster afterwards so I need the correct values in the correct locations.
What is the best way to do this?
Just do boolean masking:
mask = (array_a == -999)
new_array = np.copy(array_a)
new_array[mask] = array_b[mask]
all you need to do is
array_a[array_a==-999]=array_b[array_a==-999]
we are putting boolean condition on array elements to update should have value -999
import numpy as np
array_a =np.array([[0.564,-999,-999],
[0.234,-999,0.898],
[-999,0.124,0.687],
[0.478,0.786,-999]])
array_b =np.array([[0.324,0.254,0.204],
[0.469,0.381,0.292],
[0.550,0.453,0.349],
[0.605,0.582,0.551]])
array_a[array_a==-999]=array_b[array_a==-999]
run this snippet
One question about mask 2-d np.array data.
For example:
one 2-d np.array value in the shape of 20 x 20.
An index t = [(1,2),(3,4),(5,7),(12,13)]
How to mask the 2-d array value by the (y,x) in index?
Usually, replacing with np.nan are based on the specific value like y[y==7] = np.nan
On my example, I want to replace the value specific location with np.nan.
For now, I can do it by:
Creating a new array value_mask in the shape of 20 x 20
Loop the value and testify the location by (i,j) == t[k]
If True, value_mask[i,j] = value[i,j] ; In verse, value_mask[i,j] = np.nan
My method was too bulky especially for hugh data(3 levels of loops).
Are there some efficiency method to achieve that? Any advice would be appreciate.
You are nearly there.
You can pass arrays of indices to arrays. You probably know this with 1D-arrays.
With a 2D-array you need to pass the array a tuple of lists (one tuple for each axis; one element in the lists (which have to be of equal length) for each array-element you want to chose). You have a list of tuples. So you have just to "transpose" it.
t1 = zip(*t)
gives you the right shape of your index array; which you can now use as index for any assignment, for example: value[t1] = np.NaN
(There are lots of nice explanation of this trick (with zip and *) in python tutorials, if you don't know it yet.)
You can use np.logical_and
arr = np.zeros((20,20))
You can select by location, this is just an example location.
arr[4:8,4:8] = 1
You can create a mask the same shape as arr
mask = np.ones((20,20)).astype(bool)
Then you can use the np.logical_and.
mask = np.logical_and(mask, arr == 1)
And finally, you can replace the 1s with the np.nan
arr[mask] = np.nan
My question is inspired by another one: Intersection of 2d and 1d Numpy array I am looking for a succinct solution that does not use in1d
The setup is this. I have a numpy array of bools telling me which values of numpy array A I should set equal to 0, called listed_array. However, I want to ignore the information in the first 3 columns of listed_array and only set A to zero as indicated in the other columns of listed_array.
I know the following is incorrect:
A[listed_array[:, 3:]] = 0
I also know I can pad this subset of listed_array with a call to hstack, and this will yield correct output, but is there something more succinct?
If I understand the question, this should do it:
A[:, 3:][listed_array[:, 3:]] = 0
which is a concise version of
mask3 = listed_array[:, 3:]
A3 = A[:, 3:] # This slice is a *view* of A, so changing A3 changes A.
A3[mask3] = 0