Home > Mobile >  How to replace repeated numbers in a 1D list with the next non-repeated numbers in the list
How to replace repeated numbers in a 1D list with the next non-repeated numbers in the list

Time:09-17

I have a very long numpy array which has consequences of repeated values, for example:

My_list = [0.24, 0.02, 0.02, 0.02, 5, 7, 9, 8.4, 97, 0.56, 34, 0.45, 0.02, 0.02,
           0.02, 0.02, 0.02, 0.11, 12, 0.16, 19, 23, 27, 32, 37, 45, 0.02, 0.02,
           0.02, 0.02, 0.02, 0.02, 18, 24, 34, 45, 0.65, 68, 53, 48, 98, 78,
           564, 343, 3534, 3435, 435, 131, 2435354, 45456, 232]

How can I instead of every occurrence of the repeated number 0.02 sequence of varying length in my list, replace them with the "same next numbers sequence appearing after the repetition?

The result should be:

[0.24, 5, 7, 9, 5, 7, 9, 8.4, 97, 0.56, 34, 0.45, 0.11, 12,
 0.16, 19, 23, 0.11, 12, 0.16, 19, 23, 27, 32, 37, 45, 18, 24,
 34, 45, 0.65, 68, 18, 24, 34, 45, 0.65, 68, 53, 48, 98, 78,
 564, 343, 3534, 3435, 435, 131, 2435354, 45456, 232]

CodePudding user response:

iterate through the list backwards, keeping track of the last known unique value. if you detect a dup, then start replacing the values with the last known value until you stop hitting dups.

My_list = [0.24, 0.02, 0.02, 0.02, 5, 7, 9, 8.4, 97, 0.56, 34, 0.45, 0.02, 0.02,
           0.02, 0.02, 0.02, 0.11, 12, 0.16, 19, 23, 27, 32, 37, 45, 0.02, 0.02,
           0.02, 0.02, 0.02, 0.02, 18, 24, 34, 45, 0.65, 68, 53, 48, 98, 78,
           564, 343, 3534, 3435, 435, 131, 2435354, 45456, 232]

outlist = My_list.copy()
last_unique=My_list[-1]
print("last unique "   str(last_unique))
for i,n in reversed(list(enumerate(My_list))):
    if My_list[i]!=My_list[i-1]:
        print("non equality reassign last unique")
        print(My_list[i],My_list[i-1])
        last_unique=My_list[i]
        print(last_unique)
    elif My_list[i]==My_list[i-1]:
        outlist[i]=last_unique
print(outlist)  


[0.24, 0.02, 5, 5, 5, 7, 9, 8.4, 97, 0.56, 34, 0.45, 0.02, 0.11, 0.11, 0.11, 
0.11, 0.11, 12, 0.16, 19, 23, 27, 32, 37, 45, 0.02, 18, 18, 18, 18, 18, 18,  
24, 34, 45, 0.65, 68, 53, 48, 98, 78, 564, 343, 3534, 3435, 435, 131,  
2435354, 45456, 232]

CodePudding user response:

There are two edge cases to consider that you should decide the answers to before solving the problem.

  1. What happens if there are fewer than n elements in the list after the sequence of n repeated elements?
    e.g. [0.02, 0.02, 0.02, 5].
    Do we leave these unchanged:
    [0.02, 0.02, 0.02, 5]?
    Or delete the ones we can't replace:
    [5, 5]?
    Or replace them with None:
    [5, None, None, 5]?
  2. What happens if the next n elements also contain a repeated sequence?
    e.g. [0.02, 0.02, 0.02, 5, 10, 10, 2, 3, 4]
    Do we copy left to right:
    [5, 10, 10, 5, 2, 3, 2, 3, 4]?
    Or right to left:
    [5, 2, 3, 5, 2, 3, 2, 3, 4]?

Here's a solution that replaces from right to left and leaves unchanged repeated sequences without enough elements to replace them:

def replace_repeats(seq):
    new_seq = seq[:]
    repeat_end = len(seq)
    for i in range(len(seq)-1, -1, -1):
        if i == 0 or seq[i-1] != seq[i]:
            if repeat_end > i   1 and 2 * repeat_end - i <= len(seq):
                new_seq[i:repeat_end] = new_seq[repeat_end : 2 * repeat_end - i]
            repeat_end = i
    return new_seq
  • Related