Как разделить 2d массив (матрицу) на основе некоторого значения разделения? - PullRequest
0 голосов
/ 12 июня 2019

С учетом такой матрицы:

m = matrix(c(c(0,0,0,0,0,1,1,1,0,0),
             c(0,0,1,0,0,0,0,1,0,0),
             c(0,1,0,1,1,1,0,0,0,0),
             c(0,1,0,0,0,1,0,1,0,0),
             c(0,0,1,0,0,1,0,1,0,0),
             c(0,0,1,1,1,1,0,1,0,0),
             c(0,0,1,1,1,0,0,1,0,0),
             c(0,0,0,0,0,0,0,0,0,0)), ncol = 10, byrow = T)

Я мог бы каким-то образом применить что-то вроде одномерной split функции. Например: для строки [1]

0 1 1 0 0 1 1 1 0 0

split(row[1]) = [1 1 1], [1 1], потому что в качестве значения обрезки и обрезки я принимаю нули. Так что в моем примере с массивом я ожидаю получить 3 меньшие матрицы: М 1

a = matrix(c(c(0,1,0,0,0),
             c(1,0,1,1,1),
             c(1,0,0,0,1),
             c(0,1,0,0,1),
             c(0,1,1,1,1),
             c(0,1,1,1,0)), ncol = 5, byrow = T)

М 2

b = matrix(c(c(1,1,1),
             c(0,0,1)), ncol = 3, byrow = T)

М 3

c = matrix(c(c(1),
             c(1),
             c(1),
             c(1)), ncol = 1, byrow = T)

если я не ошибаюсь. Это какой-то простой способ добиться этого? Я сейчас код в R (но, возможно, Python). В принципе, я могу использовать его для 1D, но в 2D это становится сложнее, потому что строки зависят от столбцов. Кстати, мне нужно сохранить координаты исходного размещения.

EDIT Я отредактировал ввод, чтобы быть воспроизводимым. У меня есть хит, это растровое решение: как сохранить координаты или исходную матрицу? Это означает, что идентификаторы строк и столбцов для каждой новой матрицы из исходной матрицы.

1 Ответ

2 голосов
/ 12 июня 2019

Я не уверен на 100%, что понимаю, но вот растровое решение. Сначала я создаю матрицу.

# Create matrix
mat <- as.matrix(read.table(text  = "0 0 0 0 0 1 1 1 0 0

0 0 1 0 0 0 0 1 0 0

0 1 0 1 1 1 0 0 0 0

0 1 0 0 0 1 0 1 0 0

0 0 1 0 0 1 0 1 0 0

0 0 1 1 1 1 0 1 0 0

0 0 1 1 1 0 0 1 0 0

0 0 0 0 0 0 0 0 0 0"))

Затем я загружаю библиотеку raster и преобразую свою матрицу в растр.

# Load raster library
library(raster)
#> Loading required package: sp

# Convert to raster
ras <- raster(mat)

Здесь я нахожу скопления ячеек.

# Create clumps including diagonals
clu <- clump(ras, directions = 8)
#> Loading required namespace: igraph

Эта функция вытягивает каждую глыбу.

# Extract & trim clumps, then turn NAs to zeros
clumpy <- function(x){
  tmp <- as.matrix(trim(match(clu, x)))
  tmp[is.na(tmp)] <- 0
  tmp
}

И здесь я применяю функцию ко всем сгусткам.

lapply(unique(clu), clumpy)
#> [[1]]
#>      [,1] [,2] [,3]
#> [1,]    1    1    1
#> [2,]    0    0    1
#> 
#> [[2]]
#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    0    1    0    0    0
#> [2,]    1    0    1    1    1
#> [3,]    1    0    0    0    1
#> [4,]    0    1    0    0    1
#> [5,]    0    1    1    1    1
#> [6,]    0    1    1    1    0
#> 
#> [[3]]
#>      [,1]
#> [1,]    1
#> [2,]    1
#> [3,]    1
#> [4,]    1

Создано в 2019-06-12 пакетом Представление (v0.3.0)


Вот версия clumpy, которая сохраняет номера строк и столбцов.

# Extract & trim clumps, then turn NAs to zeros
clumpy <- function(x){
  # Find clump
  foo <- as.matrix(match(clu, x))
  # Rename columns & rows
  colnames(foo) <- 1:ncol(foo)
  rownames(foo) <- 1:nrow(foo)
  # Trim
  tmp <- as.matrix(trim(foo))
  # Replace NAs with zeros
  tmp[is.na(tmp)] <- 0
  # Return matrix
  tmp
}

# [[1]]
#   6 7 8
# 1 1 1 1
# 2 0 0 1
# 
# [[2]]
#   2 3 4 5 6
# 2 0 1 0 0 0
# 3 1 0 1 1 1
# 4 1 0 0 0 1
# 5 0 1 0 0 1
# 6 0 1 1 1 1
# 7 0 1 1 1 0
# 
# [[3]]
#   8
# 4 1
# 5 1
# 6 1
# 7 1
...