1

I have this data below:

data = np.array([[1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1],
                 [1, 1, 0, 0,-1, 0, 1, 0, 0,-1, 0],
                 [1, 0, 0, 1, 0, 0,-1, 0, 1, 0, 0],
                 [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0]])

i want to calculate how many 0 in each row and the count is for every 0 next to each other. the result I was hoping for was new array like this:

[[1 2 1 2]
 [2 1 2 1]
 [2 2 1 2]
 [2 5 2]]

and i want to search the 2 1 2 pattern ratio(also in every row) with some tolerance(if the number deviates slightly) and save the coordinate of 1 in the pattern.

so, I'll found 212, or 424, or 636, or 9 5 10(tolerated), etc

expected result:

[[0,6],[1,5],[2,7]]

those are the positions of every 1 in 212 pattern of data array

I've tried with this code below:

np.unique(data, return_counts=True, axis=1)

I fiddling with that and the result was not as I expected. This is used for image processing and the data was huge

4
  • If there are more than one 2 1 2 patterns in a row, how do you want those indicescaptured? If there are overlapping 2 1 2 (e.g. 2 1 2 1 2 1 2 1 2) patterns in a row, how do you want those indices captured? Commented Apr 9, 2020 at 18:07
  • @wwii that wouldn't happen in my data Commented Apr 9, 2020 at 19:23
  • ... See my edit - it should comply. Commented Apr 9, 2020 at 19:25
  • Your example data has eleven columns - does the real data have only eleven columns? Commented Apr 9, 2020 at 22:47

2 Answers 2

2
data = np.array([[1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1],
                 [1, 1, 0, 0,-1, 0, 1, 0, 0,-1, 0],
                 [1, 0, 0, 1, 0, 0,-1, 0, 1, 0, 0],
                 [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0]])
a = data

Counting consecutive zeros in each row:
Numpy and Python loop(s).
Iterate over rows; find the indices of the zeros; split the row where indices differ by more than one; get the shapes of the result.

for row in a:
    zeros = np.where(row==0)[0]
    neighbors = (np.argwhere(np.diff(zeros)>1)+1).ravel()
    w = np.split(zeros,neighbors)
    counts = [thing.shape[0] for thing in w]
    print(counts)

Pattern indices:
Uses some broadcasting - operates on all rows at once while iterating on columns

# pattern to search for:
# notzero,zero,zero,notzero,zero,notzero,zero,zero,notzero
pattern = np.array([False,True,True,False,True,False,True,True,False])    

# find zeros in data and pad
padded = np.pad(a==0,1)
dif = padded.shape[1] - pattern.shape[0]
for i in range(dif+1):
    stop = i+pattern.shape[0]
    test = padded[:,i:stop]
    equal =  test == pattern
    equal = np.all(equal,1)
    if any(equal):
        row = np.argwhere(equal).ravel()[0]
        print(f'[{row-1},{i+3}]')

This should find multiple (separated and overlapping) patterns in a row - seems to work with:

data = np.array([[1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1,-1, 0, 0, 1, 0,-1, 0, 0],
                 [1, 1, 0, 0,-1, 0, 1, 0, 0,-1, 0, 1, 0, 0,-1, 0, 0, 0,-1, 0, 1, 0, 0,-1],
                 [1, 0, 0, 1, 0, 0,-1, 0, 1, 0, 0,-1, 0, 1, 0, 0, 0, 1, 0, 0,-1, 0, 1, 0],
                 [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]])
Sign up to request clarification or add additional context in comments.

4 Comments

how to search the pattern as I described in my question
thanks, i think it did not work well for a huge amount of data. and how stupidly i am, i forgot about ratio, i want to find 212 pattern ratio (with some tolerance), not an exact pattern. thanks anyway. I just got another way to the true purpose of this
@ircham - please post sour solution as an answer. Can I answer my own question?
I think it's not a solution for this basic question. The real purpose is I want to detect QR Code position detection patterns in images. and this question posted because I did it from the basics. then I found another way by not processing array data from an image
1

Adapting the @jezrael answer from cumsum with reset, and assuming you can add the pandas dependency:

import pandas as pd
import numpy as np

data = np.array([[1, 0,-1, 0, 0, 1, 0,-1, 0, 0, 1],
                 [1, 1, 0, 0,-1, 0, 1, 0, 0,-1, 0],
                 [1, 0, 0, 1, 0, 0,-1, 0, 1, 0, 0],
                 [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0]])

df = pd.DataFrame(data.T, columns=range(data.shape[0]))
a = (df == 0)
df = a.cumsum()-a.cumsum().where(~a).ffill().fillna(0).astype(int)

# Add a last row of zeros 
df.loc[len(df)] = 0

# Define custom function to apply column-wise
def find_pattern(col):
    c = col.to_numpy()
    ids = np.argwhere(c==0) - 1 
    ids = ids[ids>=0]
    return [x for x in c[ids] if x!=0]

r = df.apply(lambda col: find_pattern(col), axis=0)

r
0    [1, 2, 1, 2]
1    [2, 1, 2, 1]
2    [2, 2, 1, 2]
3       [2, 5, 2]
dtype: object

The result r is a pandas Series indexed by row index, and the expected output as values.

Finally to find the [2,1,2] pattern, you can again use pandas functionalities:

r = pd.DataFrame(r, columns=['zeros'])
r['string_col'] = r['zeros'].apply(lambda row: ''.join([str(x) for x in row]))

pattern_as_string = '212'
r['pattern_index'] = r['string_col'].str.find(pattern_as_string)

         zeros  string_col  pattern_index
0  [1, 2, 1, 2]       1212              1
1  [2, 1, 2, 1]       2121              0
2  [2, 2, 1, 2]       2212              1
3     [2, 5, 2]        252             -1

Where pattern_index is the value at which the pattern starts, and it's -1 if not found.

4 Comments

it works to calculate the 0. But still confused about how to look for 2 1 2 patterns and their position in the first array. And I just found out about Pandas
@ircham edited my answer to add the pattern search. Hope it helps!
but what I need is the pattern index of the first array (data), not the new array @FBruzzesi
Then I am not sure what your expected output is since there are other values in between. Please provide what you expect as result.

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.