How to flatten a 3 dimensional array - python

I use Pyaudio to record multichannel signal (2 for example) by appending each 2-dimensional list together. Now I would like to find an efficient way to flatten the signal to one single 2 dimensional array:
For example, input is :
i = [[[ 1, 2],
[ 1, 2],
[ 1, 2]],
[[ 3, 4],
[ 3, 4],
[ 3, 4]]
]
i = np.array(i)
this i has a shape of (2,3,2), and I would like to flatten it to shape of (2x3, 2)
array([[1, 2],
[1, 2],
[1, 2],
[3, 4],
[3, 4],
[3, 4]])
Any suggestion? Many thanks

Use np.concatenate:
print(np.concatenate(i, 0))
Output:
[[1 2]
[1 2]
[1 2]
[3 4]
[3 4]
[3 4]]

It should work :
i.reshape(2*3, 2)

Use this -
[item for sublist in i for item in sublist]
[[1, 2], [1, 2], [1, 2], [3, 4], [3, 4], [3, 4]]

Related

Python indexing with simplicity

I have a numpy array a,
import numpy as np
a = np.array([[[3, 2, 2], [3, 4, 2]],
[[1, 2, 2], [3, 4, 2]],
[[1, 2, 2], [3, 4, 2]]
])
print(a)
[[[3 2 2]
[3 4 2]]
[[1 2 2]
[3 4 2]]
[[1 2 2]
[3 4 2]]]
and I want to slice part of it, right now with this way:
b = []
for i in range(a.shape[0]):
if (a[i, 0, 0] > 2 and a[i, 1, 0] > 2):
b.append(a[i])
print(np.array(b))
[[[3 2 2]
[3 4 2]]]
I tried method 1
a[np.where(a[:,:,0] > 2)]
and method 2
a[a[:,:,0]> 2]
They both result in:
array([[3, 2, 2],
[3, 4, 2],
[3, 4, 2],
[3, 4, 2]])
Is there any way to deal with the index like method 1 or 2?
You can use np.all(..., axis=1):
a[np.all(a[:, :, 0] > 2, axis=1)]
You could also use a list comprehension which allow you to fit your custom conditions.
b = [i for i in a if i[0,0]>2 and i[1,0]>2]

How can I remove one of the reverse pairs of elements from an nd numpy array without multiple for loops?

For example:
original:
[[0 2] [0 3] [1 4] [2 0] [2 3] [3 0] [3 2] [4 1]]
edited:
[[0 2] [0 3] [1 4] [2 3]]
One option: sort and get the unique values:
a = np.array([[0, 2], [0, 3], [1, 4], [2, 0], [2, 3], [3, 0], [3, 2], [4, 1]])
out = np.unique(np.sort(a), axis=0)
output:
array([[0, 2],
[0, 3],
[1, 4],
[2, 3]])
If you want to ensure keeping the original (unsorted) data:
# different example, note the initial [2, 0]
a = np.array([[2, 0], [0, 3], [1, 4], [2, 0], [2, 3], [3, 0], [3, 2], [4, 1]])
idx = np.unique(np.sort(a), axis=0, return_index=True)[1]
a[idx]
output:
array([[2, 0],
[0, 3],
[1, 4],
[2, 3]])
A fast and simple way with one for loop:
s = [[0, 2], [0, 3], [1, 4], [2, 0], [2, 3], [3, 0], [3, 2], [4, 1]]
result = []
result.append(s[0])
for x in s:
if not([x[-1],x[0]] in result) and not(x in result):
result.append(x)
result
Output:
[[0, 2], [0, 3], [1, 4], [2, 3]]

Combine numpy arrays to list if first index value is similar [duplicate]

This question already has answers here:
Merging elements in 2D list based on common first elements
(5 answers)
Closed 1 year ago.
How to combine arrays inside 2D array to a list if the first index value is the same?
Say for example, this 2D array:
[[0 0]
[0 3]
[0 4]
[1 1]
[2 2]
[3 0]
[3 3]
[3 4]
[4 0]
[4 3]
[4 4]]
How will I make it to something like this?
[[0, 0, 3, 4], [1 1], [2 2], [3 0 3 4], [4 0 3 4]]
When converting from numpy to list, I need it to be optimized as there are thousands of rows on my end.
Any suggestion is much appreciated. The end goal is I want the second index value to be combined together.
Also, take into consideration if ever the first index value is not in ascending order.
You can do it like that:
my_list = [
[0, 0],
[0, 3],
[0, 4],
[1, 1],
[2, 2],
[3, 0],
[3, 3],
[3, 4],
[4, 0],
[4, 3],
[4, 4]
]
from collections import defaultdict
d = defaultdict(list)
for i, j in my_list:
d[i].append(j)
combined = [[i]+l for i,l in d.items()]
import numpy as np
import pandas as pd
ll = [[0, 0], [0, 3], [0, 4], [1, 1], [2, 2], [3, 0], [3, 3], [3, 4], [4, 0], [4, 3], [4, 4]]
x = np.array(ll)
df = pd.DataFrame(x)
dx = df.groupby(0).apply(lambda g: g[1].tolist())
[[x[0], *x[1]] for x in zip(dx.index.tolist(), dx.values.tolist())]

how to append a 1d numpy array to a 2d numpy array python

I would like to append an array [3, 3, 3] to an array [[1, 1, 1], [2, 2, 2]], so that it becomes [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
Here is my code:
import numpy as np
arr1 = np.array([[1, 1, 1],
[2, 2, 2]])
arr2 = np.append(arr1, [3, 3, 3])
print (arr2)
instead of printing [[1, 1, 1], [2, 2, 2], [3, 3, 3]],
it prints [1, 1, 1, 2, 2, 2, 3, 3, 3].
I am quite new to numpy and I do not understand why the 2d array suddenly becomes 1d.
You can use the useful numpy's standard method of vstack.
Here is my code.
Initialize 2-dimensional numpy array
initial_array = np.array([
[1, 1, 1],
[2, 2, 2]
])
define the array to append to initiali array
new_array = np.array([3, 3, 3])
append the new array to initial array as row
result = np.vstack((initial_array, new_array))
this is the result
print(result)
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
You can read more details at here.
Hope this answer to be helpful for you. Thanks.
import numpy as np
arr1 = np.array([[1, 1, 1],
[2, 2, 2]])
arr2 = np.append(arr1, [[3, 3, 3]], axis=0)
print (arr2)
Output:
[[1 1 1]
[2 2 2]
[3 3 3]]
Use numpy.vstack:
arr2 = np.vstack((arr1, [3,3,3]))
>>> arr2
[[1 1 1]
[2 2 2]
[3 3 3]]

numpy array max min from pixelpoints of open cv [duplicate]

I have a large n x 2 numpy array that is formatted as (x, y) coordinates. I would like to filter this array so as to:
Identify coordinate pairs with duplicated x-values.
Keep only the coordinate pair of those duplicates with the highest y-value.
For example, in the following array:
arr = [[1, 4]
[1, 8]
[2, 3]
[4, 6]
[4, 2]
[5, 1]
[5, 2]
[5, 6]]
I would like the result to be:
arr = [[1, 8]
[2, 3]
[4, 6]
[5, 6]]
Ive explored np.unique and np.where but cannot figure out how to leverage them to solve this problem. Thanks so much!
Here's one way based on np.maximum.reduceat -
def grouby_maxY(a):
b = a[a[:,0].argsort()] # if first col is already sorted, skip this
grp_idx = np.flatnonzero(np.r_[True,(b[:-1,0] != b[1:,0])])
grp_maxY = np.maximum.reduceat(b[:,1], grp_idx)
return np.c_[b[grp_idx,0], grp_maxY]
Alternatively, if you want to bring np.unique, we can use it to find grp_idx with np.unique(b[:,0], return_index=1)[1].
Sample run -
In [453]: np.random.seed(0)
In [454]: arr = np.random.randint(0,5,(10,2))
In [455]: arr
Out[455]:
array([[4, 0],
[3, 3],
[3, 1],
[3, 2],
[4, 0],
[0, 4],
[2, 1],
[0, 1],
[1, 0],
[1, 4]])
In [456]: grouby_maxY(arr)
Out[456]:
array([[0, 4],
[1, 4],
[2, 1],
[3, 3],
[4, 0]])

Categories