Home > front end >  Sort a random valued 100x100 array with odd indexed rows in ascending order and even rows in descend
Sort a random valued 100x100 array with odd indexed rows in ascending order and even rows in descend

Time:04-22

I'm new to this and confused.

import numpy as np

randomnums = np.random.randint(1,100, size=(100,100))

print("Unsorted 100x100 Array:")
print(randomnums) 

def bubbleSort(randomnums):
    indexLength = len(randomnums)
    
    for i in range(indexLength-1): #for all the values in the array
         
        for x in range(1,indexLength,2): #for all the odd indexs
            if randomnums[x] > randomnums[x 1]: #if number on left is larger
                
                randomnums[x],randomnums[x 1] = randomnums[x 1], randomnums[x] #swap the values to sort in ascending order
            
        else:
            for x in range(0,indexLength,2): #for all the even indexs
              if randomnums[x] < randomnums[x 1]:
                randomnums[x], randomnums[x 1] = randomnums[x 1], randomnums[x] #swap the values to sort in descending order

CodePudding user response:

At the beginning, I thought that the rows themselves should be left unchanged, and only reordered based on their indexes (basically only reversing the order of evenly indexed ones), which would not make too much sense.

Anyway, here's an example. Note that documentation for every used function is available at [NumPy]: Routines.

code00.py:

#!/usr/bin/env python

import sys

import numpy as np


def scramble(arr):
    ret = np.empty_like(arr)
    ret[1::2] = np.sort(arr[1::2])  # Odd
    ret[::2] = np.flip(np.sort(arr[::2]), axis=-1)  # Even
    return ret


def main(*argv):
    shp = (5, 5)  # @TODO - cfati: Change this according to your requirements
    arr0 = np.random.randint(0, np.prod(shp) - 1, size=shp)
    print("Original:")
    print(arr0)
    print("\nScrambled:")
    print(scramble(arr0))


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.")
    sys.exit(rc)

Notes:

  • Oddly and evenly indexed rows, are selected via slicing

  • np.sort sorts (in ascending order only) elements inside rows based (by default) on the innermost (last, -1) axis

  • For descending order, the sorted (ascendingly) elements in in rows, must be flipped (again, based on the innermost axis - this time it must be explicitly specified, as by default it happens on all axes)

Output:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q071956865]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" code00.py
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32

Original:
[[23 14 14  5 10]
 [11 11 16  1  4]
 [10 22 17  2 14]
 [ 0  5 20  1 21]
 [16 13  5 21  5]]

Scrambled:
[[23 14 14 10  5]
 [ 1  4 11 11 16]
 [22 17 14 10  2]
 [ 0  1  5 20 21]
 [21 16 13  5  5]]

Done.

CodePudding user response:

You can sort a numpy array based on the value of a single column using np.ndarray.argsort() and then slicing. How to sort 2D array (numpy.ndarray) based to the second column in python?

Since you want to sort even- and odd-numbered rows separately, let's separate them out first:

even_rows = randomnums[::2, :]
odd_rows = randomnums[1::2, :]

Then, use the logic in the link above:

asc_order = even_rows[:, 0].argsort()
desc_order = odd_rows[:, 0].argsort()[::-1]


even_ordered_rows = even_rows[asc_order, :]
odd_ordered_rows = odd_rows[desc_order, :]

Then, set the values in the original array:

randomnums[::2, :] = even_ordered_rows
randomnums[1::2, :] = odd_ordered_rows

Let's put this all in a function:

def sort_interleaved_in_place(arr, col):
    even_rows = arr[::2, :]
    odd_rows = arr[1::2, :]

    asc_order = even_rows[:, col].argsort()
    desc_order = odd_rows[:, col].argsort()[::-1]

    even_ordered_rows = even_rows[asc_order, :]
    odd_ordered_rows = odd_rows[desc_order, :]

    arr[::2, :] = even_ordered_rows
    arr[1::2, :] = odd_ordered_rows

Starting out with a smaller (10x3) array:

>>> randomnums = np.random.randint(1, 100, (10, 3))
array([[ 7, 48, 86],
       [99, 76, 81],
       [61, 71, 33],
       [47, 41, 69],
       [35, 81, 41],
       [31,  7, 80],
       [77, 91, 14],
       [86, 38,  5],
       [73, 11, 60],
       [97, 59, 39]])

And applying this logic, we get this result:

>>> sort_interleaved_in_place(randomnums, 0)
>>> randomnums
array([[ 7, 48, 86],
       [99, 76, 81],
       [35, 81, 41],
       [97, 59, 39],
       [61, 71, 33],
       [86, 38,  5],
       [73, 11, 60],
       [47, 41, 69],
       [77, 91, 14],
       [31,  7, 80]])
  • Related