используя Delete, чтобы удалить строки и столбцы из квадратной матрицы - PullRequest
2 голосов
/ 06 января 2012

Дано: квадратная матрица и список, который представляет индекс удаляемых строк, а также одновременно представляет индекс удаляемых столбцов (это квадратная матрица, поэтому необходим только один список).

вывод: квадратная матрица, с ОБА убраны строки и столбцы в списке.

Допустим допустимый список индексов.

Это пример enter image description here

Таким образом, вышеприведенное говорит об удалении второй и 4-й строк, а также второго и 4-го столбцов.

Я не мог понять, как использовать Delete[] для одновременного удаления строк и столбцов, и я действительно не хотел составлять список для каждого отдельного индекса элемента, который я хочу удалить.

Но я мог бы использовать Delete для удаления строк.

Это ниже, как я решил, я сначала удалил строки, затем транспонировал матрицу, а затем удалил строки новой матрицы (которые будут столбцами оригинала), а затем транспонировал результат обратно, чтобы получить то, что я хотел.

как это:

a = {{0, 5, 2, 3, 1, 0}, {4, 3, 2, 5, 1, 3}, {4, 1, 3, 5, 3, 2}, {4, 
    4, 1, 1, 1, 5}, {3, 4, 4, 5, 3, 3}, {5, 1, 4, 5, 2, 0}};
del = {{2}, {4}};
a = Delete[a, del];
a = Delete[Transpose[a], del];
(a = Transpose[a]) // MatrixForm

мой вопрос: есть ли более короткий способ использования Delete (или другого из этих трюков-экспертов), чтобы сделать это лучше?

спасибо

Ответы [ 4 ]

6 голосов
/ 06 января 2012

В тех случаях, когда вы хотите удалить те же индексированные столбцы и строки, я бы использовал Part.Например, чтобы увидеть a с удаленными столбцами и строками 2 и 4:

a[[{1, 3, 5, 6}, {1, 3, 5, 6}]] // MatrixForm

Чтобы сделать это более общим, вы можете создать нечто, в котором вы объедините DeleteCases с Range и списком столбцов/ индексы строк, но в отсутствие дополнительной информации я не пытался это сделать (пока).

Редактировать

remove[a_?MatrixQ, pos_List] := Module[{tmp, length = Length[a]},

  tmp = DeleteCases[Range[length], Alternatives @@ pos];

  a[[tmp, tmp]]

  ]

remove[a,{2,4}]
{{0, 2, 1, 0}, {4, 3, 3, 2}, {3, 4, 3, 3}, {5, 4, 2, 0}}

Редактировать2

remove2[a_?MatrixQ, pos_List] := Module[{tmp, length = Length[a]},

  tmp = Complement[Range[length], pos];

  a[[tmp, tmp]]

  ]

remove2[a,{2,4}]
{{0, 2, 1, 0}, {4, 3, 3, 2}, {3, 4, 3, 3}, {5, 4, 2, 0}}

протестируйте оба из них на предмет вашей реальной проблемы.

4 голосов
/ 06 января 2012

Это должен быть более быстрый способ удаления строк, чем метод двойной транспонирования:

a = {{0, 5, 2, 3, 1, 0},
     {4, 3, 2, 5, 1, 3},
     {4, 1, 3, 5, 3, 2},
     {4, 4, 1, 1, 1, 5},
     {3, 4, 4, 5, 3, 3},
     {5, 1, 4, 5, 2, 0}};
del = {{2}, {4}};

a = MapThread[Delete, {a, Table[del, {Length[a]}]}]

Время варьируется, но в этом несколько надуманном примере оно быстрее:

a = Table[RandomReal[], {1000}, {10000}];
del = Map[List, Union[Table[RandomInteger[{1, 10000}], {100}]]];
Timing[Transpose[Delete[Transpose[a], del]];]

{0.25, Null}

Timing[MapThread[Delete, {a, Table[del, {Length[a]}]}];]

(0,125, ноль}

1 голос
/ 13 января 2012

Это гораздо менее эффективно, чем метод Part, но я нахожу его несколько более прозрачным, и бывают моменты, которые имеют большее значение.

ReplacePart[a, {{2}, {4}, {_, 2}, {_, 4}} :> Sequence[]]
0 голосов
/ 06 января 2012

Вы можете, конечно, сделать свой пример с Drop:

Drop[a, {2, 4, 2}, {2, 4, 2}] // MatrixForm

Я не знаю, как это вообще, но, возможно, это поможет вам направиться в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...