randomly sample from a high dimensional array along with a specific dimension - python-3.x

There has a 3-dimensional array x of shape (2000,60,5). If we think it represents a video, the 2000 can represent 2000 frames. I would like to randomly sample it along with the first dimension, i.e., get a set of frame samples. For instance, how to get an array of (500,60,5) which is randomly sampled from x along with the first dimension?

You can pass x as the first argument of the choice method. If you don't want repeated frames in your sample, use replace=False.
For example,
In [10]: x = np.arange(72).reshape(9, 2, 4) # Small array for the demo.
In [11]: x
Out[11]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]],
[[16, 17, 18, 19],
[20, 21, 22, 23]],
[[24, 25, 26, 27],
[28, 29, 30, 31]],
[[32, 33, 34, 35],
[36, 37, 38, 39]],
[[40, 41, 42, 43],
[44, 45, 46, 47]],
[[48, 49, 50, 51],
[52, 53, 54, 55]],
[[56, 57, 58, 59],
[60, 61, 62, 63]],
[[64, 65, 66, 67],
[68, 69, 70, 71]]])
Sample "frames" from x with the choice method of NumPy random generator instance.
In [12]: rng = np.random.default_rng()
In [13]: rng.choice(x, size=3)
Out[13]:
array([[[40, 41, 42, 43],
[44, 45, 46, 47]],
[[40, 41, 42, 43],
[44, 45, 46, 47]],
[[16, 17, 18, 19],
[20, 21, 22, 23]]])
In [14]: rng.choice(x, size=3, replace=False)
Out[14]:
array([[[ 8, 9, 10, 11],
[12, 13, 14, 15]],
[[32, 33, 34, 35],
[36, 37, 38, 39]],
[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]]])
Note that the frames will be in random order; if you want to preserve the order, you could use choice to generate an array of indices, then use the sorted indices to pull the frames out of x.

Related

Is there any possibility to Merage element in sublist with another one by using certain condition?

merge element of sublist with another sublist without duplicate
I am working on solving the vehicle routing problem and get the initial best solution and I want to be exploited and need to get rid of duplicate nodes while merging them.
my problem I want to merge the sublist of element [8] with others that carry the condition equal to 3 elements, but cause there are two sets consist 3 elements like [18, 22, 34, 8], [35, 36, 37, 8] and I need integrate element 8 in one of them randomly
bestsolution= [[22, 15, 20, 2, 32, 30, 4, 17], [27, 8, 9, 14, 33, 21, 5, 13], [26, 28, 6, 31, 11], [18,22,34],[35,36,37],[8]]
for a in bestsolution:
if len(a)==1:
p=a
del bestsolution[-1]
for b in bestsolution:
if len(b)==2:
b.extend(p)
print("p",b)
print("bestsolution1-2",bestsolution)
elif len(b)==3:
b.extend(p)
print("p",b)
print("bestsolution1-3",bestsolution)
my results:
p [18, 22, 34, 8]
bestsolution1-3 [[22, 15, 20, 2, 32, 30, 4, 17], [27, 8, 9, 14, 33, 21, 5, 13], [26, 28, 6, 31, 11], [18, 22, 34, 8], [35, 36, 37]]
p [35, 36, 37, 8]
bestsolution1-3 [[22, 15, 20, 2, 32, 30, 4, 17], [27, 8, 9, 14, 33, 21, 5, 13], [26, 28, 6, 31, 11], [18, 22, 34, 8], [35, 36, 37, 8]]
where for each run program, I got two results at the same time so how could be refuse the second solution.
'''
code targeted:
bestsolution1-3 [[22, 15, 20, 2, 32, 30, 4, 17], [27, 8, 9, 14, 33, 21, 5, 13], [26, 28, 6, 31, 11], [18, 22, 34], [35, 36, 37, 8]]
'''
Thank you
Ans/
The code will be:
'''
bestsolution= [[22, 15, 20, 2, 32, 30, 4, 17],[2,3,4], [27, 8, 9, 14, 33, 21, 5, 13], [26, 28, 6, 31, 11], [18,22,34],[35,36,37],[8]]
if len(a)==1:
p=a
del bestsolution[-1]
for b in bestsolution:
if len(b)==2:
b.extend(p)
print("p",b)
print("bestsolution1-2",bestsolution)
break
elif len(b)==3:
b.extend(p)
print("p",b)
print("bestsolution1-3",bestsolution)
break
elif len(b)==4:
b.extend(p)
print("p",b)
print("bestsolution1-4",bestsolution)
break
'''
Output expected:
p [18, 22, 34, 8]
bestsolution1-3 [[22, 15, 20, 2, 32, 30, 4, 17], [27, 8, 9, 14, 33, 21, 5, 13], [26, 28, 6, 31, 11], [18, 22, 34, 8], [35, 36, 37]]
'''
After trying much time I got final results, really didn't expect that I solved by putting the keyword (Break) will prevent execute the program in the second iteration so we will get one solution only.
if anyone have a comment, it will be a pleasure.

How to sort YOLOv4 bounding box?

I have trained the yolov4 from alexeyab darknet repo to detect characters in a number plate. It segments the character correctly but the bounding boxes are in random order. How can I sort the bounding box from top left to bottom right for image like this: (This is not actual image used but this is a photoshoped image for sample Nepali License Number Plate because of confidential data)
I've tried: (from pyimagesearch)
def sort_bbox(bbox, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = sorted(bbox, key=lambda b: b[1], reverse=reverse)
# return the list of sorted contours and bounding boxes
return boundingBoxes
but didn't sort the bounding boxes. It's still in random order.
I have bounding box from yolov4 detection like this: unsorted bounding boxes in xywh: [[50, 12, 15, 18], [66, 10, 15, 19], [87, 10, 19, 20], [21, 12, 24, 19], [51, 12, 15, 17], [51, 12, 15, 18], [66, 12, 15, 18], [86, 11, 19, 19], [39, 32, 27, 29], [68, 33, 28, 27], [97, 31, 28, 30], [12, 37, 24, 25], [11, 35, 25, 27], [40, 34, 27, 28], [68, 33, 27, 27], [97, 33, 28, 28]]
and from above sorting code: [[66, 10, 15, 19], [87, 10, 19, 20], [86, 11, 19, 19], [50, 12, 15, 18], [21, 12, 24, 19], [51, 12, 15, 17], [51, 12, 15, 18], [66, 12, 15, 18], [97, 31, 28, 30], [39, 32, 27, 29], [68, 33, 28, 27], [68, 33, 27, 27], [97, 33, 28, 28], [40, 34, 27, 28], [11, 35, 25, 27], [12, 37, 24, 25]]
What I want is the bounding box of: बा २ प ८ ८ ८ ८
Any Help will be very much appreciated.

In a list of list objects, how do i compare each list object with all other list objects?

I have a list with multiple list objects in it, I wish to compare each inner list to all other inner lists in the outer list object and if a match is found, print it out.
I have already tried looping through each object in the list and compare it to all other objects but I always match the one I start with.
My example list is this:
list_of_lists = [
[1, 11, 17, 21, 33, 34],
[4, 6, 10, 18, 22, 25],
[1, 15, 20, 22, 23, 31],
[3, 5, 7, 18, 23, 27],
[3, 22, 24, 25, 28, 37],
[7, 11, 12, 25, 28, 31],
[1, 11, 17, 21, 33, 34],
...
]
Note that list_of_lists[0] matches list_of_lists[6], which I wish to match in this example.
The expected result is a loop that goes through each list object and compares it to all other objects, if there's a match - print it out.
You could do something like this:
list_of_lists = [
[1, 11, 17, 21, 33, 34],
[4, 6, 10, 18, 22, 25],
[1, 15, 20, 22, 23, 31],
[3, 5, 7, 18, 23, 27],
[3, 22, 24, 25, 28, 37],
[7, 11, 12, 25, 28, 31],
[1, 11, 17, 21, 33, 34],
]
for i in range(len(list_of_lists)):
for j in range(len(list_of_lists)):
# If you're checking the row against itself, skip it.
if i == j:
break
# Otherwise, if two different lists are matching, print it out.
if list_of_lists[i] == list_of_lists[j]:
print(list_of_lists[i])
This outputs:
[1, 11, 17, 21, 33, 34]

remove element from the list then display list without element that remove

I have this nested list:
a = [[1, 3, 6, 11, 16, 21, 25, 28, 31, 32, 33, 34, 35, 36],
[1, 2, 5, 9, 15, 20, 24, 26, 30, 36],
[1, 3, 6, 11, 16, 21, 25, 29, 31, 32, 33, 34, 35, 36],
[1, 2, 4, 8, 14, 18, 23, 36],
[1, 2, 5, 9, 15, 20, 24, 27, 30, 36],
[1, 3, 6, 11, 16, 22, 25, 28, 31, 32, 33, 34, 35, 36],
[1, 3, 7, 12, 17, 36],
[1, 2, 4, 8, 14, 19, 23, 36],
[1, 2, 5, 10, 15, 20, 24, 26, 30, 36],
[1, 3, 6, 11, 16, 22, 25, 29, 31, 32, 33, 34, 35, 36],
[1, 2, 5, 10, 15, 20, 24, 27, 30, 36],
[1, 3, 6, 11, 16, 21, 25, 28, 31, 32, 33, 35, 36],
[1, 3, 6, 11, 16, 21, 25, 28, 31, 33, 34, 35,36],
[1, 3, 6, 11, 16, 21, 25, 29, 31, 32, 33, 35, 36]]
I need to choose max length of sublist in nested list, than compare item of sublist with nested list. If item in sublist equal then same item in nested list remove and in final print nested list without this item.
I hope I understand your question correctly.
You want input to be:
a = [[1, 3, 6, 11, 16, 21, 25, 28, 31, 32, 33, 34, 35, 36],
[1, 2, 5, 9, 15, 20, 24, 26, 30, 36],
[1, 3, 6, 11, 16, 21, 25, 29, 31, 32, 33, 34, 35, 36],
[1, 2, 4, 8, 14, 18, 23, 36],
[1, 2, 5, 9, 15, 20, 24, 27, 30, 36],
[1, 3, 6, 11, 16, 22, 25, 28, 31, 32, 33, 34, 35, 36],
[1, 3, 7, 12, 17, 36],
[1, 2, 4, 8, 14, 19, 23, 36],
[1, 2, 5, 10, 15, 20, 24, 26, 30, 36],
[1, 3, 6, 11, 16, 22, 25, 29, 31, 32, 33, 34, 35, 36],
[1, 2, 5, 10, 15, 20, 24, 27, 30, 36],
[1, 3, 6, 11, 16, 21, 25, 28, 31, 32, 33, 35, 36],
[1, 3, 6, 11, 16, 21, 25, 28, 31, 33, 34, 35, 36],
[1, 3, 6, 11, 16, 21, 25, 29, 31, 32, 33, 35, 36]]
We are removing
[1, 3, 6, 11, 16, 22, 25, 29, 31, 32, 33, 34, 35, 36]
and
[1, 3, 6, 11, 16, 21, 25, 29, 31, 32, 33, 34, 35, 36]
since they are of the same length.
The output should be:
a = [[1, 2, 5, 9, 15, 20, 24, 26, 30, 36],
[1, 2, 4, 8, 14, 18, 23, 36],
[1, 2, 5, 9, 15, 20, 24, 27, 30, 36],
[1, 3, 7, 12, 17, 36],
[1, 2, 4, 8, 14, 19, 23, 36],
[1, 2, 5, 10, 15, 20, 24, 26, 30, 36],
[1, 2, 5, 10, 15, 20, 24, 27, 30, 36],
[1, 3, 6, 11, 16, 21, 25, 28, 31, 32, 33, 35, 36],
[1, 3, 6, 11, 16, 21, 25, 28, 31, 33, 34, 35, 36],
[1, 3, 6, 11, 16, 21, 25, 29, 31, 32, 33, 35, 36]]
with the previous lists removed.
Your question was not worded clearly, but I hope this is what you wanted. Here is the code:
# assume a is not empty
d = {} # list of the max length -> number of occurrences in 2d array
# find the length of the longest list
maxLen = len(a[0])
for l in a:
if len(l) > maxLen:
maxLen = len(l)
# add lists of the same max length and their count to the dictionary
for l in a:
if len(l) == maxLen:
#convert list to string because python does not support list being key of a dictionary
l_string = str(l)
if l_string in d:
d[l_string] += 1
else:
d[l_string] = 1
# remove
for l_string in d:
while d[l_string] > 0:
# convert string back to list and remove
a.remove(eval(l_string))
d[l_string] -= 1
# test result if you want
for row in a:
print(row)

Extract random 2d windows of a 2d numpy array

import numpy as np
arr = np.array(range(60)).reshape(6,10)
arr
> array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
> [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
> [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
> [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
> [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
> [50, 51, 52, 53, 54, 55, 56, 57, 58, 59]])
What I need:
select_random_windows(arr, number_of windows= 3, window_size=3)
> array([[[ 1, 2, 3],
> [11, 12, 13],
> [21, 22, 23]],
>
> [37, 38, 39],
> [47, 48, 49],
> [57, 58, 59]],
>
> [31, 32, 33],
> [41, 42, 43],
> [51, 52, 53]]])
In this hypothetical case I'm selecting 3 windows of 3x3 within the main array (arr).
My actual array is a raster and I basically need a bunch (on the thousands) of little 3x3 windows.
Any help or even a hint will be much appreciated.
I actually haven't found any practical solution yet...since many many hours
THX!
We can leverage np.lib.stride_tricks.as_strided based scikit-image's view_as_windows to get sliding windows. More info on use of as_strided based view_as_windows.
from skimage.util.shape import view_as_windows
def select_random_windows(arr, number_of_windows, window_size):
# Get sliding windows
w = view_as_windows(arr,window_size)
# Store shape info
m,n = w.shape[:2]
# Get random row, col indices for indexing into windows array
lidx = np.random.choice(m*n,number_of_windows,replace=False)
r,c = np.unravel_index(lidx,(m,n))
# If duplicate windows are allowed, use replace=True or np.random.randint
# Finally index into windows and return output
return w[r,c]
Sample run -
In [209]: arr
Out[209]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59]])
In [210]: np.random.seed(0)
In [211]: select_random_windows(arr, number_of_windows=3, window_size=(2,4))
Out[211]:
array([[[41, 42, 43, 44],
[51, 52, 53, 54]],
[[26, 27, 28, 29],
[36, 37, 38, 39]],
[[22, 23, 24, 25],
[32, 33, 34, 35]]])
You can try [numpy.random.choice()][1]. It takes a 1D or an ndarray and creates a single element or an ndarray by sampling the elements from the given ndarray. You also have an option of providing the size of the array you want as the output.

Resources