y = np.array([1, 1, 0, 0])
print("Y 1:", y)
y = y.T
print("Y 2:", y)
Both print the same:
[1,1,0,0]
The numpy array a = [1,1,0,0] shape is [4,] and b= [[1,1,0,0]] is [1,4]. Can I say that a is a vector and b is a matrix. So the transpose operation doesn't work for vector so the two prints are the same.
As you can see from the documentation here, transposing a 1-D array returns an unchanged view of the original array. In your case, y is a 1-D array, hence the transposed output will be unchanged.
numpy distinguishes 1d "vectors" from 2d "row vectors" and "column vectors". it's common to switch between them using something like:
# create 1d vector
v = np.array([1, 1, 0, 0])
# row vector
rv = v[np.newaxis, :]
# column vector
cv = v[:, np.newaxis]
note that np.newaxis is defined to be None, so you'll often see this written as, e.g. v[:,None] and because needing a column vector is such a common operation there are obscure shorthands like np.c_[v]
now that rv and cv are 2d they can be transposed as you were expecting
switching back to a 1d vector is similar:
# from row vector
v = rv[0, :]
# from column vector
v = cv[:, 0]
Related
Say I have, as an arbitrary example, two 2d numpy arrays, X and Y where
X = np.array([[0,1,2,3],
[4,5,6,7]])
Y = np.array([[1,2,3,4],
[1,1,7,3]])
I want to create a new 2d numpy array, Z, that is the argmax of X,Y element-wise so Z would be, in this example:
Z = np.array([[1,2,3,4],
[4,5,7,7]])
I've tried variations of the following none return the intended result
np.array([(np.argmax(X,Y))]) --> error
I know I can do this simply by using a nested for loop but that isn't very efficient for very large datasets. Is there an efficient, numpy-specific, way to create a new 2d array (Z, in the example above) composed of the argmax by element from two 2d arrays (X and Y, in the example above)?
You're looking for np.maximum:
>>> np.maximum(X, Y)
array([[1, 2, 3, 4],
[4, 5, 7, 7]])
which compares the arrays element-wise and returns the maximum for each of them.
Use numpy.where:
Z = np.where(X > Y, X, Y)
Here, the first argument X > Y compares X and Y element by element, and returns a boolean array of the comparison. Then we use the boolean array to build Z: if the element at an index is True, it uses the value from X, and if it is False it uses the value from Y.
My goal is to interpolate the discretized continuous 2D Fourier transform of a function. The problem seems to be that the frequencies in each dimension are not output in strictly ascending order (see here).
The fft.fft2 function accepts a 2D array, where in my case the array (let's call it A) is structured such that A[i][j] = fun(x[i], y[j]), fun being the function to be transformed. After applying fft.fft2 to A, output is an array F of the same dimensions as the original array, such that the frequency coordinate corresponding to F[i][j] is (w_x[i], w_y[j]), where w_x = fft.fftfreq(F.shape[0]) and w_y = fft.fftfreq(F.shape[1]), both of these being 1D arrays which are not in ascending order.
Over wx and wy I am wanting to interpolate F (say to a function finterp) such that the interpolated value is returned upon calling finterp(w_x, w_y), w_x and w_y being within the domain of wx and range of wy, but otherwise arbitrary. I've looked into the varieties of interpolation available through scipy.interpolate, but it doesn't seem to me that any of them can deal with this type of data structure (the coordinate axes being defined as out-of-order 1D arrays and the function values being in a 2D array).
This is a little abstract, so here I've made up a simple example which is similar in structure to the above. Suppose we are wishing to construct a continuous function f(x, y) = x + y over the region x = [-1, 1] and y = [-1, 1] given the following data:
import numpy as np
# note that below z[i][j] corresponds to what we want f(x[i], y[j]) to be
x = np.array([0, 1, -1])
y = np.array([0, 1, -1])
z = np.array([0, 1, -1],[1, 2, 0],[-1, 0, -2])
z[i][j] we know corresponds to the function evaluated at x[i], y[j]. How can one either (a) interpolate this data directly, given its original structure, or (b) rearrange the data so that x and y are in ascending order, and the arranged z is such that z[i][j] is equal to the function evaluated at the rearranged x[i], y[j]?
The following code shows how to use fftshift to change the output of fft2 and fftfreq so that the frequency axes are monotonically increasing. After applying fftshift, you can use the arrays for interpolation. I've added display of the arrays so that you can verify that the data itself is unchanged. The origin is shifted from the top-left corner to the middle of the array, moving the negative frequencies from the right side to the left side.
import numpy as np
import matplotlib.pyplot as pp
x = np.array([0, 1, -1])
y = np.array([0, 1, -1])
z = np.array([[0, 1, -1],[1, 2, 0],[-1, 0, -2]])
f = np.fft.fft2(z)
w_x = np.fft.fftfreq(f.shape[0])
w_y = np.fft.fftfreq(f.shape[1])
pp.figure()
pp.imshow(np.abs(f))
pp.xticks(np.arange(0,len(w_x)), np.round(w_x,2))
pp.yticks(np.arange(0,len(w_y)), np.round(w_y,2))
f = np.fft.fftshift(f)
w_x = np.fft.fftshift(w_x)
w_y = np.fft.fftshift(w_y)
pp.figure()
pp.imshow(np.abs(f))
pp.xticks(np.arange(0,len(w_x)), np.round(w_x,2))
pp.yticks(np.arange(0,len(w_y)), np.round(w_y,2))
pp.show()
An alternative approach is to not use fftfreq to determine your frequencies, but compute them by hand. The FFT, by default, computes the DFT for k=[0..N-1]. Because of the periodicity, with the DFT at k equal to the DFT at k+N and k-N, its output is often interpreted to have k=[N//2...(N-1)//2] instead (but arranged differently to match k=[0..N-1]); this is the k that fftfreq returns (it returns k/N).
Thus, you can instead say
N = f.shape[0]
w_x = np.linspace(0, N, N, endpoint=False) / N
Now you don't have any negative frequencies, and instead have frequencies in the range [0,N-1]/N.
I have a 2D array which describes index ranges for a 1D array like
z = np.array([[0,4],[4,9]])
The 1D array
a = np.array([1,1,1,1,0,0,0,0,0,1,1,1,1])
I want to have a view on the 1D array with the index range defined by z. So, for only the first range
a[z[0][0]:z[0][1]]
How to get it for all ranges? Is it possible to use as_strided with unequal lengths defined by z as shape? I want to avoid to copy data, actually I only want a different view on a for further computation.
In [66]: a = np.array([1,1,1,1,0,0,0,0,0,1,1,1,1])
In [67]: z = np.array([[0,4],[4,9]])
So generating the slices from the rows of z we get 2 arrays:
In [68]: [a[x[0]:x[1]] for x in z]
Out[68]: [array([1, 1, 1, 1]), array([0, 0, 0, 0, 0])]
Individually those arrays are views. But together they aren't an array. The lengths diff, so they can't be vstacked into a (2,?) array. They can be hstacked but that won't be a view.
The calculation core of np.array_split is:
sub_arys = []
sary = _nx.swapaxes(ary, axis, 0)
for i in range(Nsections):
st = div_points[i]
end = div_points[i + 1]
sub_arys.append(_nx.swapaxes(sary[st:end], axis, 0))
Ignoring the swapaxes bit, this is doing the same thing as my list comprehension.
for x, y in z:
array_view = a[x:y]
# do something with array_view
I have this subcode in Python and I cannot understand what it is or what it does, especially this statement:
X[:,:,:,i]
The subcode is:
train_dict = sio.loadmat(train_location)
X = np.asarray(train_dict['X'])
X_train = []
for i in range(X.shape[3]):
X_train.append(X[:,:,:,i])
X_train = np.asarray(X_train)
Y_train = train_dict['y']
for i in range(len(Y_train)):
if Y_train[i]%10 == 0:
Y_train[i] = 0
Y_train = to_categorical(Y_train,10)
return (X_train,Y_train)
This is called array slicing. As #cᴏʟᴅsᴘᴇᴇᴅ mentioned, x is a 4D array and X[:,:,:,i] gets one specific 3D array slice of it.
Maybe an example with fewer dimensions can help.
matrix = np.arange(4).reshape((2,2))
In this case matrix is a bidimensional array:
array([[0, 1],
[2, 3]])
Therefore matrix[:, 1] will result in a smaller slice of matrix:
array([1, 3])
In original code matrix[:,:,:, 1] each of the first : mean something like "all elements in this dimension".
Have a look at how array slicing works in numpy here.
I want to use numpy.ix_ to generate an multi-dimensional index for a 2D space of values. However, I need to use a subindex to look up the indices for one dimension. For example,
assert subindex.shape == (ny, nx)
data = np.random.random(size=(ny,nx))
# Generator returning the index tuples
def get_idx(ny,nx,subindex):
for y in range(ny):
for x in range(nx):
yi = y # This is easy
xi = subindex[y,x] # Get the second index value from the subindex
yield (yi,xi)
# Generator returning the data values
def get_data_vals(ny,nx,data,subindex):
for y in range(ny):
for x in range(nx):
yi = y # This is easy
xi = subindex[y,x] # Get the second index value from the subindex
yield data[y,subindex[y,x]]
So instead of the for loops above, I'd like to use a multi-dimensional index to index data Using numpy.ix_, I guess I would have something like:
idx = numpy.ix_([np.arange(ny), ?])
data[idx]
but I don't know what the second dimension argument should be. I'm guessing it should be something involving numpy.choose?
What you actually seem to want is:
y_idx = np.arange(ny)[:,np.newaxis]
data[y_idx, subindex]
BTW, you could achieve the same thing with y_idx = np.arange(ny).reshape((-1, 1)).
Let's look at a small example:
import numpy as np
ny, nx = 3, 5
data = np.random.rand(ny, nx)
subindex = np.random.randint(nx, size=(ny, nx))
Now
np.arange(ny)
# array([0, 1, 2])
are just the indices for the "y-axis", the first dimension of data. And
y_idx = np.arange(ny)[:,np.newaxis]
# array([[0],
# [1],
# [2]])
adds a new axis to this array (after the existing axis) and effectively transposes it. When you now use this array in an indexing expression together with the subindex array, the former gets broadcasted to the shape of the latter. So y_idx becomes effectively:
# array([[0, 0, 0, 0, 0],
# [1, 1, 1, 1, 1],
# [2, 2, 2, 2, 2]])
And now for each pair of y_idx and subindex you look up an element in the data array.
Here you can find out more about "fancy indexing"
It sounds like you need to do two things:
Find all indices into the data array and
Translate the column indices according to some other array, subindex.
The code below therefore generates indices for all array positions (using np.indices), and reshapes it to (..., 2) -- a 2-D list of coordinates representing each position in the array. For each coordinate, (i, j), we then translate the column coordinate j using the subindex array provided, and then use that translated index as the new column index.
With numpy, it is not necessary to do that in a for-loop--we can simply pass in all the indices at once:
i, j = np.indices(data.shape).reshape((-1, 2)).T
data[i, subindex[i, j]]