What's the numpy equivalent of python's zip(*)? - python

I think (hope) this question differs substantially from What is the equivalent of "zip()" in Python's numpy?, although it might just be my ignorance.
Let's say I have the following:
[[[ 1, 2],
[ 3, 4],
[ 5, 6]],
[[ 7, 8],
[ 9, 10],
[11, 12]]]
and I want to turn it into
[[[ 1, 2],
[ 7, 8]],
[[ 3, 4],
[ 9, 10]],
[[ 5, 6],
[11, 12]]]
In python I can do:
>>> foo
[[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]
>>> zip(*foo)
[([1, 2], [7, 8]), ([3, 4], [9, 10]), ([5, 6], [11, 12])]
But how can I do this with numpy arrays (without using zip(*))?

Do you actually need to return tuples or do you want to reshape the array?
>>> a
array([[[ 1, 2],
[ 3, 4],
[ 5, 6]],
[[ 7, 8],
[ 9, 10],
[11, 12]]])
>>> a.swapaxes(0,1)
array([[[ 1, 2],
[ 7, 8]],
[[ 3, 4],
[ 9, 10]],
[[ 5, 6],
[11, 12]]])

Related

How to rotate 90 deg of 2D array inside 3D array?

I have a 3D array consist of 2D arrays, I want to rotate only the 2D arrays inside the 3D array without changing the order, so it will become a 3D array consist of rotated 3D arrays.
For example, I have a 3D array like this.
foo = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(foo)
>>> array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
foo.shape
>>> (2, 2, 3)
I want to rotate it into this.
rotated_foo = np.array([[[4, 1], [5, 2], [6, 3]], [[10, 7], [11, 8], [12, 9]]])
print(rotated_foo)
>>> array([[[ 4, 1],
[ 5, 2],
[ 6, 3]],
[[10, 7],
[11, 8],
[12, 9]]])
rotated_foo.shape
>>> (2, 3, 2)
I've tried it using numpy's rot90 but I got something like this.
rotated_foo = np.rot90(foo)
print(rotated_foo)
>>> array([[[ 4, 5, 6],
[10, 11, 12]],
[[ 1, 2, 3],
[ 7, 8, 9]]])
rotated_foo.shape
>>> (2, 2, 3)
You can use numpy.rot90 by setting axes that you want to rotate.
foo = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
rotated_foo = np.rot90(foo, axes=(2,1))
print(rotated_foo)
Output:
array([[[ 4, 1],
[ 5, 2],
[ 6, 3]],
[[10, 7],
[11, 8],
[12, 9]]])
Try np.transpose and np.flip:
print(np.flip(np.transpose(foo, (0, 2, 1)), axis=2))
Prints:
[[[ 4 1]
[ 5 2]
[ 6 3]]
[[10 7]
[11 8]
[12 9]]]
You want to rotate 90 in the opposite direction of np.rot90, or equivalently rotate by 270 = 3 * 90 in the np.rot90 direction:
>>> np.rot90(foo, k=3, axes=(1, 2))
array([[[ 4, 1],
[ 5, 2],
[ 6, 3]],
[[10, 7],
[11, 8],
[12, 9]]])

How to transfer List of nested lists into a NumPy array?

I have the following sample object:
list_sample = [['N', [], None], ['B:maj', [3, 6, 11], 11], ['C#:maj', [1, 5, 8], 1], ['Bb:min', [1, 5, 10], 10], ['Eb:min/b3', [3, 6, 6, 10], 6], ['B:maj', [3, 6, 11], 11], ['C#:maj', [1, 5, 8], 1], ['F#:maj', [1, 6, 10], 6], ['F#:maj', [1, 6, 10], 6], ['B:maj', [3, 6, 11], 11], ['C#:maj', [1, 5, 8], 1], ['Bb:min', [1, 5, 10], 10], ['Eb:min', [3, 6, 10], 3], ['B:maj', [3, 6, 11], 11]]
I would like to transfer this list into a ndarray, so I tried this method suggested in this postDebugging Numpy VisibleDeprecationWarning (ndarray from ragged nested sequences):
np.array(formatted_chords,dtype = object)
But it gives me undesired result like this:
[['N' list([]) None]
['B:maj' list([3, 6, 11]) 11]
['C#:maj' list([1, 5, 8]) 1]
['Bb:min' list([1, 5, 10]) 10]
['Eb:min/b3' list([3, 6, 6, 10]) 6]
['B:maj' list([3, 6, 11]) 11]]
My target output would a ndarray which looks like this:
[['N',[],None]
['B:maj',[3, 6, 11]),11]
['C#:maj',[1, 5, 8]),1]
['Bb:min',[1, 5, 10]),10]
['Eb:min/b3',[3, 6, 6, 10],6]
['B:maj',[3, 6, 11],11]]
Can anybody shares how to do this transformation?

flatten list of numpy arrays while keeping inner arrays

l = [np.array([[1,2],[3,4]]), np.array([5,6]), np.array([[7,8],[9,10],[11,12]])]
I'm trying to flatten this list of arrays but keeping the inner arrays:
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
I tried itertools.chain, np.concatenate, np.flatten but none of these options give the output above
Your arrays have different numbers of dimensions, you need to ensure they all are 2D:
out = np.concatenate([x[None,:] if x.ndim == 1 else x for x in l])
output:
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])
or with itertools.chain with a list output:
from itertools import chain
list(chain.from_iterable([x.tolist()] if x.ndim == 1 else x.tolist()
for x in l))
output: [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
You haven't provided your desired output. But, as I understood, you are looking for this:
x = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
print([n for m in x for n in m])
with output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Please let me know if this is not your desired output.
You basically need to flatten each subarray, concatenate them and finally reshape it.
np.concatenate(list(map(np.ravel, l))).reshape(-1, 2)
output:
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])

Numpy append vectors of same shape to different axis

I have a numpy array
import numpy as np
initial_array = np.array([[
[0, 1],
[1, 2],
[2, 3],
[3, 4]],
[[4, 5],
[5, 6],
[6, 7],
[7, 8]]])
I have an array I want to add in:
to_add = np.array([
[ 8, 9],
[ 9, 10],
[10, 11],
[11, 12]])
Here, initial_array has a shape of (2, 4, 2) and to_add has a shape of (4, 2). I'm looking for the final result with a shape (3, 4, 2):
result = np.array([[
[ 0, 1],
[ 1, 2],
[ 2, 3],
[ 3, 4]],
[[ 4, 5],
[ 5, 6],
[ 6, 7],
[ 7, 8]],
[[ 8, 9],
[ 9, 10],
[10, 11],
[11, 12]]])
How can this be done without converting the numpy array back to a python list, is it possible to do this using numpy alone?
A lot of ways actually, I'm showing a couple:
>>> result = np.insert(initial_array, initial_array.shape[0], to_add, axis=0)
# or
>>> result = np.vstack((initial_array,to_add[None,...]))
# or
>>> result = np.array([*initial_array, to_add])
In addition to the other answers, you can also do that with np.newaxis():
np.concatenate([initial_array, to_add[np.newaxis, :]])
The result:
Out[75]:
array([[[ 0, 1],
[ 1, 2],
[ 2, 3],
[ 3, 4]],
[[ 4, 5],
[ 5, 6],
[ 6, 7],
[ 7, 8]],
[[ 8, 9],
[ 9, 10],
[10, 11],
[11, 12]]])
Without reshape:
np.concatenate((initial_array, [to_add]))
You could just add an additional axis to to_add so they can be directly concatenated:
np.concatenate([initial_array, to_add[None,:]])
array([[[ 0, 1],
[ 1, 2],
[ 2, 3],
[ 3, 4]],
[[ 4, 5],
[ 5, 6],
[ 6, 7],
[ 7, 8]],
[[ 8, 9],
[ 9, 10],
[10, 11],
[11, 12]]])
You can use numpy.append with to_add inside a list and appending only on the axis 0.
initial_array = np.array([[
[0, 1],
[1, 2],
[2, 3],
[3, 4]],
[[4, 5],
[5, 6],
[6, 7],
[7, 8]]])
to_add = np.array([
[ 8, 9],
[ 9, 10],
[10, 11],
[11, 12]])
final = np.append(initial_array, [to_add], axis=0)

Extracting patches of a certain size from the image in python efficiently

I have an image and I want to extract square patches of different sizes from it.
I need dense patches, that is, I need a patch at every pixel in the image.
For example if the image is 100x100 and the patch size is 64.
The result will be 10000 patches of size 64x64
These are the same patches which we use for filtering operations for example.
In case there is a boundary I would like to mirror the image.
What is the most efficient way of extracting patches using python?
Thanks
I think you are looking for something like this:
http://scikit-image.org/docs/0.9.x/api/skimage.util.html#view-as-windows
sklearn
You might want to have a look at sklearn.feature_extraction.image.extract_patches_2d and skimage.util.pad:
>>> from sklearn.feature_extraction.image import extract_patches_2d
>>> import numpy as np
>>> A = np.arange(4*4).reshape(4,4)
>>> window_shape = (2, 2)
>>> B = extract_patches_2d(A, window_shape)
>>> B[0]
array([[0, 1],
[4, 5]])
>>> B
array([[[ 0, 1],
[ 4, 5]],
[[ 1, 2],
[ 5, 6]],
[[ 2, 3],
[ 6, 7]],
[[ 4, 5],
[ 8, 9]],
[[ 5, 6],
[ 9, 10]],
[[ 6, 7],
[10, 11]],
[[ 8, 9],
[12, 13]],
[[ 9, 10],
[13, 14]],
[[10, 11],
[14, 15]]])
skimage
Expanding the answer of Stefan van der Walt a bit:
Install skimage
On Ubuntu
$ sudo apt-get install python-skimage
or
$ pip install scikit-image
Example from the docs
>>> from skimage.util import view_as_windows
>>> import numpy as np
>>> A = np.arange(4*4).reshape(4,4)
>>> A
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> window_shape = (2, 2)
>>> B = view_as_windows(A, window_shape)
>>> B[0]
array([[[0, 1],
[4, 5]],
[[1, 2],
[5, 6]],
[[2, 3],
[6, 7]]])
>>> B
array([[[[ 0, 1],
[ 4, 5]],
[[ 1, 2],
[ 5, 6]],
[[ 2, 3],
[ 6, 7]]],
[[[ 4, 5],
[ 8, 9]],
[[ 5, 6],
[ 9, 10]],
[[ 6, 7],
[10, 11]]],
[[[ 8, 9],
[12, 13]],
[[ 9, 10],
[13, 14]],
[[10, 11],
[14, 15]]]])

Categories

Resources