adding two three dimensional numpy array: - numpy-ndarray

I have two numpy array : X shape is (68,44,13) and X_toadd shape is: (68,44,7)I want to add them together in a way that I will  have X_new shape as (68,44, 20). So, I need to keep the first two dimensions of X and add the 7 columns from X_toadd's third dimension to the 13 columns.
how should I do that?
add, append, and concatenate are tried but the result is not what I want which should have the shape (68,44,20)!

You need to specify which axis to use to glue things together.
Here, -1 denotes the first axis from the the back.
import numpy as np
a,b = np.zeros((68,44,13)), np.zeros((68,44,7))
c = np.concatenate([a,b], axis=-1)
c.shape
(68, 44, 20)

Related

Access Z coordinate in a LINESTRING Z in geopandas?

I have a GeoDataFrame with a LINESTRING Z geometry where Z is my altitude for the lat/long. (There are other columns in the dataframe that I deleted for ease of sharing but are relevant when displaying the resulting track)
TimeUTC Latitude Longitude AGL geometry
0 2021-06-16 00:34:04+00:00 42.835413 -70.919610 82.2 LINESTRING Z (-70.91961 42.83541 82.20000, -70...
I would like to find the maximum Z value in that linestring but I am unable to find a way to access it or extract the x,y,z values in a way that I can determine the maximum value outside of the linestring.
line.geometry.bounds only returns the x,y min/max.
The best solution I could come up with was to turn all the points into a list of tuples:
points = line.apply(lambda x: [y for y in x['geometry'].coords], axis=1)
And then find the maximum value of the third element:
from operator import itemgetter
max(ft2,key=itemgetter(2))[2]
I hope there is a better solution available.
Thank you.
You can take your lambda function approach and just take it one step further:
import numpy as np
line['geometry'].apply(lambda geom: np.max([coord[2] for coord in geom.coords]))
Here's a fully reproducible example from start to finish:
import shapely
import numpy as np
import geopandas as gpd
linestring = shapely.geometry.LineString([[0,0,0],
[1,1,1],
[2,2,2]])
gdf = gpd.GeoDataFrame({'id':[1,2,3],
'geometry':[linestring,
linestring,
linestring]})
gdf['max_z'] = (gdf['geometry']
.apply(lambda geom:
np.max([coord[2] for coord in geom.coords])))
In the example above, I create a new column called "max_z" that stores the maximum Z value for each row.
Important note
This solution will only work if you exclusively have LineStrings in your geometries. If, for example, you have MultiLineStrings, you'll have to adapt the function I wrote to take care of that.

Getting the dimensions of a numpy array right to plot converted greyscale image

as part of Unity's ML Agents images fed to a reinforcement learning agent can be converted to greyscale like so:
def _process_pixels(image_bytes=None, bw=False):
s = bytearray(image_bytes)
image = Image.open(io.BytesIO(s))
s = np.array(image) / 255.0
if bw:
s = np.mean(s, axis=2)
s = np.reshape(s, [s.shape[0], s.shape[1], 1])
return s
As I'm not familiar enough with Python and especially numpy, how can I get the dimensions right for plotting the reshaped numpy array? To my understanding, the shape is based on the image's width, height and number of channels. So after reshaping there is only one channel to determine the greyscale value. I just didn't find a way yet to plot it yet.
Here is a link to the mentioned code of the Unity ML Agents repository.
That's how I wanted to plot it:
plt.imshow(s)
plt.show()
Won't just doing this work?
plt.imshow(s[..., 0])
plt.show()
Explanation
plt.imshow expects either a 2-D array with shape (x, y), and treats it like grayscale, or dimensions (x, y, 3) (treated like RGB) or (x, y, 4) (treated as RGBA). The array you had was (x, y, 1). To get rid of the last dimension we can do Numpy indexing to remove the last dimension. s[..., 0] says, "take all other dimensions as-is, but along the last dimension, get the slice at index 0".
It looks like the grayscale version has an extra single dimension at the end. To plot, you just need to collapse it, e.g. with np.squeeze:
plt.imshow(np.squeeze(s))

plot curves that are described by a matrix in matlab

I have a matrix, where the row is generated by X = [0:0.01:10] and the column is generated by Y = [20:-0.01:5] The numbers in the matrix are either 0, 1 or 9 which partitions the matrix in to 3 distinct regions. I want to generate a XYplot such that it draws the boundaries of these regions that are captured by the numbers in the matrix.
Is there a clever way of achieving this goal in matlab?
Yes, you can use contour and specify the levels on which to draw contours. In your case you want to draw a line on the 1 and 9 values.
contour(X, Y, thematrix, [1, 9])
where thematrix is the name of your matrix.

Sort for plotting data (julia+pyplot)

Consider the following simple code
using PyPlot
x = [2,5,3,4]
y = [1,2,3,4]
plot(x,y,".-")
As you note the lines that connect the points on the graph are displayed according to the order of the data into the arrays. I mean, the first "point x-y" (2,1) is connected to the point (5,2), that is connected to (3,3) and so on.
How do I get a graph that reflects this piece of code:
using PyPlot
x = [2,3,4,5]
y = [1,3,4,2]
plot(x,y,".-")
?
Or in other words, how can I sort the x-array and preserve the x-y correspondence?

Matlab mode filter for dependent RGB channels

I've been performing a 2D mode filter on an RGB image by running medfilt2 independently on the R,G and B channels. However, splitting the RGB channels like this gives artifacts in the colouring. Is there a way to perform the 2D median filter while keeping RGB values 'together'?
Or, I could explain this more abstractly: Imagine I had a 2D matrix, where each value contained a pair of index coordinates (i.e. a cell matrix of 2X1 vectors). How would I go about performing a median filter on this?
Here's how I can do an independent mode filter (giving the artifacts):
r = colfilt(r0,[5 5],'sliding',#mode);
g = colfilt(g0,[5 5],'sliding',#mode);
b = colfilt(b0,[5 5],'sliding',#mode);
However colfilt won't work on a cell matrix.
Another approach could be to somehow combine my RGB channels into a single number and thus create a standard 2D matrix. Not sure how to implement this, though...
Any ideas?
Thanks for your help.
Cheers,
Hugh
EDIT:
OK, so problem solved. Here's how I did it.
I adapted my question so that I'm no longer dealing with (RGB) vectors, but (UV) vectors. Still essentially the same problem, except that my vectors are 2D not 3D.
So firstly I load the individual U and V channels, arrange them each into a 1D list, then combine them, so I essentially have a list of vectors. Then I reduce it to just those which are unique. Then, I assign each pixel in my matrix the value of the index of that unique vector. After this I can do the mode filter. Then I basically do the reverse, in that I go through the filtered image pixelwise, and read the value at each pixel (i.e. an index in my list), and find the unique vector associated with that index and insert it at that pixel.
% Create index list
img_u = img_iuv(:,:,2);
img_v = img_iuv(:,:,3);
coordlist = unique(cat(2,img_u(:),img_v(:)),'rows');
% Create a 2D matrix of indices
img_idx = zeros(size(img_iuv,1),size(img_iuv,2),2);
for y = 1:length(Y)
for x = 1:length(X)
coords = squeeze(img_iuv(x,y,2:3))';
[~,idx] = ismember(coords,coordlist,'rows');
img_idx(x,y) = idx;
end
end
% Apply the mode filter
img_idx = colfilt(img_idx,[n,n],'sliding',#mode);
% Re-construct the original image using the filtered data
for y = 1:length(Y)
for x = 1:length(X)
idx = img_idx(x,y);
try
coords = coordlist(idx,:);
end
img_iuv(x,y,2:3) = coords(:);
end
end
Not pretty but it gets the job done. I suppose this approach would also work for RGB images, or other similar situations.
Cheers,
Hugh
I don't see how you can define the median of a vector variable. You probably need to reduce the R,G,B components to a single value and then compunte the median on that value. Why not use the intensity level as that single value? You could do it easily with rgb2gray.

Resources