Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Grouping algorithm
#1
As the title says I'm trying to write a grouping algorithm, although I'm not sure if that is the right term to describe what I need. Here a better explanation: I have a matrix m rows by n columns, each cell contains a value that is either 0 or 1; I need an algorithm that, given a coordinate to a cell of the matrix, if that cell contains a '1' returns a list of the "group" of all the adjacent cells that contains '1' values plus all the adjacent cells to the cells adjacent to the first one and so on (a adjacent cell to another is a cell that i vertically, horizontally or diagonally adjacent).
Example:
matrix = [
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
]
In this case, given the cell
coord = (0, 4)
returns this list:
group = [(0, 4), (1, 3), (1, 4), (2, 2), (2, 4)]
This is the problem, I don't necessarily need an algorithm, a guidance to research about this topic would also be appreciated. Thanks in advance.
Reply
#2
You can solve it with numpy:

import numpy as np


matrix = [
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
]
group = [index for index, value in np.ndenumerate(matrix) if value == 1]
Without numpy:
[(i,j) for i, row in enumerate(matrix) for j, val in enumerate(row) if val == 1]
Decomposed:
group = []
for i, row in enumerate(matrix):
    for j, val in enumerate(row):
        if val == 1:
            group.append((i, j))
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
(May-19-2020, 10:28 AM)DeaD_EyE Wrote: You can solve it with numpy:

import numpy as np


matrix = [
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
]
group = [index for index, value in np.ndenumerate(matrix) if value == 1]
Without numpy:
[(i,j) for i, row in enumerate(matrix) for j, val in enumerate(row) if val == 1]
Decomposed:
group = []
for i, row in enumerate(matrix):
    for j, val in enumerate(row):
        if val == 1:
            group.append((i, j))

That is not what I need, in fact my example does not explain my needs well, I'll try and explain it again.
I have this matrix
matrix = [
    [0,0,0,1,1,0],
    [0,1,1,1,0,0],
    [0,0,0,0,0,0],
    [1,0,1,0,1,0],
]
If the coordinates are
coord = (0, 3)
the list returned must be
group = [(0, 3), (0, 4), (1, 1), (1, 2), (1, 3)]
; the '1' in the last row must be ignored given that they are not adjacent to
 (0, 3)
nor to any of its adjacent (ora adjacent to adjacent...).
Reply
#4
matrix = [
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
]

def get_cells(matrix, r, c):
    """Return list of continuous matches of matrix[r][c].  A continuous
    match is if a cell left, right, above or below has the same value.
    """
    def check_adjacent(coord, r, c):
        # Append (coord[0]+r, coord[1]+c) if equal value
        r += coord[0]
        c += coord[1]
        if 0 <= r < len(matrix) and 0 <= c < len(matrix[0]):
            if not (r, c) in coords and matrix[r][c] == value:
                coords.append((r, c))

    value = matrix[r][c]
    coords = [(r, c)]
    for coord in coords:
        # Look all around for a match.  Appending to list used
        # for iteration provided an implicit interpolation
        check_adjacent(coord,-1,0)
        check_adjacent(coord,1, 0)
        check_adjacent(coord,0,-1)
        check_adjacent(coord,0,1)
    return coords

x = get_cells(matrix, 3, 3)
x.sort()
print(x)
Reply
#5
(May-19-2020, 12:07 PM)deanhystad Wrote:
matrix = [
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
]

def get_cells(matrix, r, c):
    """Return list of continuous matches of matrix[r][c].  A continuous
    match is if a cell left, right, above or below has the same value.
    """
    def check_adjacent(coord, r, c):
        # Append (coord[0]+r, coord[1]+c) if equal value
        r += coord[0]
        c += coord[1]
        if 0 <= r < len(matrix) and 0 <= c < len(matrix[0]):
            if not (r, c) in coords and matrix[r][c] == value:
                coords.append((r, c))

    value = matrix[r][c]
    coords = [(r, c)]
    for coord in coords:
        # Look all around for a match.  Appending to list used
        # for iteration provided an implicit interpolation
        check_adjacent(coord,-1,0)
        check_adjacent(coord,1, 0)
        check_adjacent(coord,0,-1)
        check_adjacent(coord,0,1)
    return coords

x = get_cells(matrix, 3, 3)
x.sort()
print(x)

I tested that on some cases and it seems to work perfectly, just one little problem: if I want to consider adjacent aven cells that are diagonally connected to each other, how do I have to edit that code?
Reply
#6
Add diagonal checks inside the for loop. You would add a check_adjacent(coord, 1, 1) for example.
Reply
#7
(May-19-2020, 01:11 PM)deanhystad Wrote: Add diagonal checks inside the for loop. You would add a check_adjacent(coord, 1, 1) for example.

Perfect, thank you very much for your answers
Reply
#8
Bad comment in my program. Appending to the list used for iteration provides an implicit recursion. This is a recursive algorithm without an recursive function call.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Grouping Data based on 30% bracket purnima1 4 1,195 Mar-10-2023, 07:38 PM
Last Post: deanhystad
  Grouping and sum of a list of objects Otbredbaron 1 3,208 Oct-23-2021, 01:42 PM
Last Post: Gribouillis
  Grouping and summing of dataset jef 0 1,642 Oct-04-2020, 11:03 PM
Last Post: jef
  Help Grouping by Intervals on list paul41 1 2,124 Dec-03-2019, 09:43 PM
Last Post: michael1789
  Grouping a list of various time into intervals paul41 1 3,783 Nov-24-2019, 01:47 PM
Last Post: buran
  resample grouping pr0blem olufemig 1 1,960 Nov-06-2019, 10:45 PM
Last Post: Larz60+
  Splitting lines ang grouping three at once samsonite 5 2,764 Jun-21-2019, 05:19 PM
Last Post: ichabod801
  Grouping csv by name terrydidi 8 3,906 Jan-14-2019, 09:27 AM
Last Post: perfringo
  Function for grouping variables Scott 1 2,707 Nov-13-2018, 03:01 AM
Last Post: ichabod801
  Python grouping program GhostZero199 2 3,304 Jul-18-2017, 12:44 PM
Last Post: sparkz_alot

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020