Is there a way to apply numpy.extract to a 3d-array? - python

I have the following:
X = np.ndarray (324,349,24)
y = np.ndarray (324,349)
I would like to create a dictionary to house conditional extraction, to wit:
myDict = {'keyA':cond,'keyB':cond,'keyC':cond,'keyD':cond}
Each key in myDict.keys() is represented numerically within y. What I would like to do is apply a mask and extract only those indices within X that correspond to the set mask.
For example,
condA = y==0
...
condD = y==3
How would I go about applying those condition on X? I was thinking something along these lines:
for k in range(1, X.shape[2]):
myDict['keyA'] = np.extract(condA,k)
myDict['keyB'] = np.extract(condB,k)
myDict['keyC'] = np.extract(condC,k)
myDict['keyD'] = np.extract(condD,k)
However, I get the error:
IndexError: index is out of bounds for size
Expected Output:
A dictionary:
myDict{'keyA':ndarray [n,n,24],'keyB':ndarray[n,n,24],'keyC':ndarray[n,n,24],'keyD':ndarray[n,n,24]}

The numpy function wheremay be useful here:
myDict['keyA'] = X.where(condA)

Related

How to replace all elements of a list using a for loop

Question
The question here asks to make two lists/arrays in python and fill it with 0s initially and then occupy them with the relevant values.
import numpy as np
x = []
y = []
for i in range (0,101):
x.append(0)
y.append(0)
xx = np.linspace(1,10,101)
print(xx)
for a in range (len(y)):
for j in xx:
fx = np.log(j)
y[a] = fx
for b in range (len(x)):
for k in xx:
x[b] = k
print(x)
print(" ")
print(y)
I used a nested for loop to traverse through the values in the xx list and used the log function and stored the values in a variable and then replace the 0s in the (y)list with the function values over each iteration. Same thing with the x list but just replace the 0s with the value of the variable which is used in the function respectively.
However the output I keep getting is not right and I can't get what is going wrong within the loops. The output should show the values of x in the first list and the values of f(x) in the second list however it only shows the value of the last x in the range as well as the value of the last f(x) in the range.
Output
I'm guessing you are supposed to use linspace, and enumerate:
import numpy as np
size = 101
x = np.zeros(size)
y = np.zeros(size)
for i, n in enumerate(np.linspace(1,10,size)):
x[i] = n
y[i] = np.log(n)

Delete 2D unique elements in a 2D NumPy array

I generate a set of unique coordinate combinations by using:
axis_1 = np.arange(image.shape[0])
axis_1 = np.reshape(axis_1,(axis_1.shape[0],1))
axis_2 = np.arange(image.shape[1])
axis_2 = np.reshape(axis_2,(axis_2.shape[0],1))
coordinates = np.array(np.meshgrid(axis_1, axis_2)).T.reshape(-1,2)
I then check for some condition and if it is satisfied i want to delete the coordinates from the array.
Something like this:
if image[coordinates[i,0], coordinates[i,1]] != 0:
remove coordinates i from coordinates
I tried the remove and delete commands but one doesn't work for arrays and the other simply just removes every instance where coordinates[i,0] and coordinates[i,1] appear, rather than the unique combination of both.
You can use np.where to generate the coordinate pairs that should be removed, and np.unique combined with masking to remove them:
y, x = np.where(image > 0.7)
yx = np.column_stack((y, x))
combo = np.vstack((coordinates, yx))
unique, counts = np.unique(combo, axis=0, return_counts=True)
clean_coords = unique[counts == 1]
The idea here is to stack the original coordinates and the coordinates-to-be-removed in the same array, then drop the ones that occur in both.
You can use the numpy.delete function, but this function returns a new modified array, and does not modify the array in-place (which would be quite problematic, specially in a for loop).
So your code would look like that:
nb_rows_deleted = 0
for i in range(0, coordinates.shape[0]):
corrected_i = i - nb_rows_deleted
if image[coordinates[corrected_i, 0], coordinates[corrected_i, 1]] != 0:
coordinates = np.delete(coordinates, corrected_i, 0)
nb_rows_deleted += 1
The corrected_i takes into consideration that some rows have been deleted during your loop.

How to selectively substract a pair indexs from an array using python

I have an array of 10 elements, and I would like to compute the following
a = [1,2,3,4,5,6,7,8,9,10]
and wish to do the following operation:
k = [a[1]-a[0], a[3]-a[2], a[5]-a[4], a[7]-a[6], a[9]-a[8]]
I wish to extend this operation any array size.
For a list with even elements you could build upon the following:
a = [1,3,5,7,9,11,13,15,17,19]
m = []
for i in range(1,len(a)-1):
m.append([a[i] - a[i-1]])
print(m)

Computing an average based on lists in another function

So I need to generate a mean for both the list of x coordinates and the list of y coordinates from one function using another function, but I'm not exactly sure how to do so. Here's what I've got so far, the first function is correct, it's just the second one that needs work, I'm just not sure what to do. 'datafile1' is simply a list of x and y coordinates separated by a tab. I should mention that this has to be done through a separate function, otherwise I would have just done this in a more simpler way.
import math
import statistics
def fileRead():
"Reads the input file and stores the x and y coordinates in a parallel list"
dataFile = open('datafile1.txt', 'r')
dataList = [] # list comprised of x and y pairs
x = [] # list comprised of just x coordinates
y = [] # list comprised of just y coordinates
for dataLine in dataFile:
dataList.append(dataLine)
dataSplit = dataLine.split()
x.append(float(dataSplit[0]))
y.append(float(dataSplit[1]))
return x, y
def getMean(dataList):
"Computes the mean of the data set"
dataMean = statistics.mean(dataList)
return dataMean
Since calculating the mean isn't exactly complex (it's just a function call), why don't you just calculate it inline right after calling fileRead()?
(x, y) = fileRead()
xMean = statistics.mean(x)
yMean = statistics.mean(y)

Python-1D indice link with 2D array location

Introduction
Sometimes, I want to get the value of an 2-d array at a random location.
For example, there is an array data in the shape of (20,20). There is a random number-pair (5,5). Then, I get the data[5,5] as my target value.
On the purpose of using genetic algorithm. I want to get the samples from an 2-d array as several individuals. So, I want to generate an linked table which connect an 1d value to 2d position.
My attempt
## data was the 2-d array in the shape of 20x20
data = np.random.randint(0,1000,400)
data = data.reshape(20,20)
## direction was my linked table
direction = {"Indice":[],"X":[],"Y":[]}
k = 0
for i in range(0,data.shape[0],1):
for j in range(0,data.shape[1],1):
k+=1
direction["Indice"].append(k)
direction["X"].append(j)
direction["Y"].append(i)
direction = pd.DataFrame(direction)
## generate an random int and connect with the 2-d value.
loc = np.random.randint(0,400)
XX = np.array(direction[direction.Indice == loc ].X)
YY = np.array(direction[direction.Indice == loc ].Y)
target_value = data[YY,XX]
My question
Are there any neat way to achieve my attempt?
Any advice would be appreciate!
You could use np.ravel to make data 1-dimensional, then index it using the flat index loc:
target_value = data.ravel()[loc-1]
Or, if you want XX and YY, perhaps you are looking for np.unravel_index. It maps a flat index or an array of flat indices to a tuple of coordinates.
For example, instead of building the direction DataFrame, you could use
np.unravel_index(loc-1, data.shape)
instead of
XX = np.array(direction[direction.Indice == loc ].X)
YY = np.array(direction[direction.Indice == loc ].Y)
Then you could define target_value as :
target_value = data[np.unravel_index(loc-1, data.shape)]
Alternatively, to simply get a random value from the 2D array data, you could use
target_value = np.random.choice(data.flat)
Or to get N random values, use
target_values = np.random.choice(data.flat, size=(N,))
Why the minus one in loc-1:
In your original code, the direction['Indice'] column uses k values which
start at 1, not 0. So when loc equals 1, the 0th-indexed row of direction is
selected. I used loc-1 to make
target_value = data[np.unravel_index(loc-1, data.shape)]
return the same result that
XX = np.array(direction[direction.Indice == loc ].X)
YY = np.array(direction[direction.Indice == loc ].Y)
target_value = data[YY,XX]
returns. Note however, that if loc equals 0, then np.unravel_index(-1, data.shape) raises a ValueError, while your original code would return an empty array for target_value.

Categories