1

I want to be able to sort a given array into 4-dimensional columns. The ONLY size of this actual array is 2-dimensional [[...], [...]], but I want to be able to convert any given array into this 2d (4d columns) array.

So say I have a the input array, and b the output array:

a = [1, 2, 3, 4, 5, 6, 7, 8]
b = [
        [1, 3, 5, 7], # notice the pattern
        [2, 4, 6, 8]
    ]

Another case:

a = [1, 2, 3, 4, 5, 6]
b = [
        [1, 3, 5, None], 
        [2, 4, 6, None]
    ]

Another case:

a = [1, 2, 3, 4, ..., 100]
b = [
        [1, 26, 51, 76], 
        [2, 27, 52, 77], 
        ..., 
        [25, 50, 75, 100]
    ]

I've looked around online for this sort of formatting, but could only find reshaping using Numpy.

5
  • It is not a 4dim array but a 2dim array. What have you tried so far? Commented Jul 7, 2022 at 9:24
  • its not 4 dimensional, its 4 values in each array and 2 dimensional Commented Jul 7, 2022 at 9:25
  • what is a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]? Commented Jul 7, 2022 at 9:25
  • @GeekyQuentin following the theme, i'd think its this imgur.com/a/MhTzlsW Commented Jul 7, 2022 at 9:38
  • oh yeah sorry my bad english Commented Jul 8, 2022 at 1:45

3 Answers 3

2

You can use numpy to achieve this. In the core, it's simply padding a with NaN values until you have enough values to fill the desired 2-D structure. Then, you just have to reshape the array. Note that we first reshape into the transposed shape, and then transpose it afterwards to get the shape that we want. This way, the values appear in the right order.

import numpy as np

def get_data(a):
    # Number of columns. You can change this if you want.
    data_shape_1 = 4 

    # Calculate nominal number of rows
    data_shape_0 = np.ceil(a.shape[0]/float(shape_1)).astype('int')

    # Pad a such that it fits the 2-D "data_shape_0 x data_shape_1" array
    a_padded = np.concatenate([a, [np.nan]*(data_shape_0*data_shape_1 - a.shape[0])]) 

    # Reshape into transposed data shape, then re-transpose to get the right order.
    return a_padded.reshape([data_shape_1, data_shape_0]).T

Let's test your examples (and an extra example):

print(" First example")
a_0 = np.arange(1,101)
print(a_0)

data_0 = get_data(a_0)
print(data_0)

print("\n Second example")
a_1 = np.arange(1,5)
print(a_1)

data_1 = get_data(a_1)
print(data_1)

print("\n Third example")
a_2 = np.arange(1,9)
print(a_2)

data_2 = get_data(a_2)
print(data_2)

print("\n Fourth example")
a_2 = np.arange(1,7)
print(a_2)

data_2 = get_data(a_2)
print(data_2)

print("\n Extra example")
a_3 = np.arange(1,15)
print(a_3)

data_3 = get_data(a_3)
print(data_3)

Output:

First example
[  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  72
  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
  91  92  93  94  95  96  97  98  99 100]
[[  1.  26.  51.  76.]
 [  2.  27.  52.  77.]
 [  3.  28.  53.  78.]
 [  4.  29.  54.  79.]
 [  5.  30.  55.  80.]
 [  6.  31.  56.  81.]
 [  7.  32.  57.  82.]
 [  8.  33.  58.  83.]
 [  9.  34.  59.  84.]
 [ 10.  35.  60.  85.]
 [ 11.  36.  61.  86.]
 [ 12.  37.  62.  87.]
 [ 13.  38.  63.  88.]
 [ 14.  39.  64.  89.]
 [ 15.  40.  65.  90.]
 [ 16.  41.  66.  91.]
 [ 17.  42.  67.  92.]
 [ 18.  43.  68.  93.]
 [ 19.  44.  69.  94.]
 [ 20.  45.  70.  95.]
 [ 21.  46.  71.  96.]
 [ 22.  47.  72.  97.]
 [ 23.  48.  73.  98.]
 [ 24.  49.  74.  99.]
 [ 25.  50.  75. 100.]]

 Second example
[1 2 3 4]
[[1. 2. 3. 4.]]

 Third example
[1 2 3 4 5 6 7 8]
[[1. 3. 5. 7.]
 [2. 4. 6. 8.]]

 Fourth example
[1 2 3 4 5 6]
[[ 1.  3.  5. nan]
 [ 2.  4.  6. nan]]

 Extra example
[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14]
[[ 1.  5.  9. 13.]
 [ 2.  6. 10. 14.]
 [ 3.  7. 11. nan]
 [ 4.  8. 12. nan]]

Observe the mixed column of NaN's and actual values in the extra example. This is how the code will behave, you'll have to decide if that's the behavior you expect.

Sign up to request clarification or add additional context in comments.

Comments

0
import numpy as np
from math import ceil

data = [x for x in range(1, 9)]
required_len = ceil(len(data) / 4) * 4
t_2 = required_len // 4
data = data + [None] * (required_len - len(data))
data = np.array(data ).reshape(4, t_2).T

Here I generate an array data of some arbitrary length which afterwards I fill up with Nones, so that it has a length, divisable by 4.

Then, using numpy, I reshape this array such that the first dimension is of length 4 and the second has the remainder. If I transpose that I get exactly what you requested.

Comments

0

So from the examples provided, I think I've come up with a raw Python implementation and for extra points I've implemented it using n-dimensions. I'm no mathematician... But I spent some time working through cases since I enjoy math problems.

from math import ceil, floor

"""
Converts a 1d array into a 4d-col 2d-array.
"""
def conv(a, dims=4):
    # Pre-calculating the rows required.
    l = len(a) # length of original a
    t = ceil(l/dims) # total cols required
    r = [[Nonedims] for _ in range(t)] # return array
    print(f"Array is of length {l}, and requires {t} rows")

    # Iterating over the length of the a-array.
    for i in range(l):
        v = a[i] # value
        # Calculating our row/col (x/y).
        x = i%t
        y = floor(i/t)
        r[x][y] = v 
    return r

# Invoke converter, then iterate through rows to display results easier.
a = conv([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
for r in a:
    print(r)

2 Comments

just [[None]*dims] * t no needs for comprehensions
@cards good idea will do

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.