0

The array is 'num_array':

[1 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1
 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2
 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2 3
 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1 1 2 3 1
 2 3 1 2 3 3 2 1 3 2 1 3 2 1]

I've tried to use a for loop:

a = num_array [:3]
b = num_array.reshape(int(len(num_array)/len(a)), int(len(a)))
print(num_array)
for a in np.nditer(num_array):
        print (b)

But it doesn't come out right because it's not identical as it only checks the first 3 indices (a). I'm a python beginner of 2 months

  • What output do you want to get? – alani Jul 04 '20 at 11:52
  • I got: ` [1 2 3] [1 2 3] [1 2 3] [3 2 1] [3 2 1] [3 2 1] [1 2 3] [1 2 3] [1 2 3] [3 2 1] [3 2 1] [3 2 1]] ` *not all characters – Daniel Ogunfadebo Jul 04 '20 at 12:00
  • But i want to get identical rows i.e: r0 = r1 = r2 ... = rn – Daniel Ogunfadebo Jul 04 '20 at 12:09
  • using a function that takes `[num_array]` argument – Daniel Ogunfadebo Jul 04 '20 at 12:14
  • 3
    Your problem is not specified exactly enough yet, I think. What do you mean by "I want to get identical rows"? Does the input always have the structure of repeated sub-arrays? Or are you looking for an algorithm that finds out whether there are such repetitions? – David Wierichs Jul 04 '20 at 12:17
  • I'm trying to define a function that takes in an array that has a randomly repeated number pattern (eg: `[2 3 5 6 2 3 5 7 5 6 2 3 5 6 2 3 5 7 5 6]`). I want to loop through the array and group each pattern: '2356235756' for example into separate rows and increment iterator by 1 each loop. In this example, it would return 2 but should also work for any set of number pattern. – Daniel Ogunfadebo Jul 04 '20 at 12:43

1 Answers1

0

The following code tries all the divisors of the array length and then checks whether all sub-arrays are equal. Providing -1 as parameter in reshape(-1, k) automatically calculates the correct dimension. (Note that the loop to get the divisors is quite simplistic, it could be sped up e.g. as in this post.)

import numpy as np

def find_repeat_length(num_array):
    n = num_array.size
    for k in range(1, n + 1):
        if n % k == 0:  # if k is a divisor of n
            arr = num_array.reshape(-1, k)
            if (arr == arr[0]).all(): # check wether all rows are equal to each other
                return k
num_array_1 = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 3, 2, 1, 3, 2, 1, 3, 2, 1])
num_array_2 = np.array([1, 2, 3, 3, 2, 1, 1, 5, 1, 2, 3, 3, 2, 1, 1, 5, 1, 2, 3, 3, 2, 1, 1, 5])

for num_array in (num_array_1, num_array_2):
    rep_len = find_repeat_length(num_array)
    print(f'repeat length is {rep_len}: {num_array[:rep_len]} repeated {len(num_array) // rep_len} times')

Result:

repeat length is 18: [1 2 3 1 2 3 1 2 3 3 2 1 3 2 1 3 2 1] repeated 9 times
repeat length is 8: [1 2 3 3 2 1 1 5] repeated 3 times
JohanC
  • 71,591
  • 8
  • 33
  • 66
  • Thanks for the feedback, however, running the function provided on `num_array2 = np.array([1, 2, 3, 3, 2, 1, 1, 5, 1, 2, 3, 3, 2, 1, 1, 5, 1, 2, 3, 3, 2, 1, 1, 5])` it gives `repeat length is 8: [1 2 3 1 2 3 1 2]` where I expect: `[1 2 3 3 2 1 1 5]` – Daniel Ogunfadebo Jul 04 '20 at 14:42
  • Maybe something went wrong with copy-pasting? I just changed my code to your new example and the result seems to be OK. – JohanC Jul 04 '20 at 15:19
  • Yes! I didn't copy the last ` // rep_len} times') ` of your code. Thanks, it works – Daniel Ogunfadebo Jul 04 '20 at 16:04