Assuming I have the a 5x7 matrix below: b = ((1, 4, 9, 16, 25, 4, 2), (36, 49, 64, 81, 100, 5, 1), (121, 144, 169, 196, 225, 8, 9), (256, 289, 324, 361, 400, 9, 5), (441, 484, 529, 576, 625, 3, 7)) I want to set some elements on each row and different column to zero. such that, I will have: b[[(Row1, column 2;;3 and column 5;;7),(Row2, column 1;;2 and column 4;;7),(Row3, column 1;;4 and column 6;;7),(Row4, column 2;;3 and column 6;;7),(Row5, column 1;;4 and column 6;;7)]]=0
Asked
Active
Viewed 595 times
4
1 Answers
5
b = {{1, 4, 9, 16, 25, 4, 2}, {36, 49, 64, 81, 100, 5, 1}, {121, 144, 169, 196, 225, 8, 9},
{256, 289, 324, 361, 400, 9, 5}, {441, 484, 529, 576, 625, 3, 7}};
cols = {{2 ;; 3, 5 ;; 7}, {1 ;; 2, 4 ;; 7}, {1 ;; 4, 6 ;; 7},
{2 ;; 3, 6 ;; 7}, {1 ;; 4, 6 ;; 7}};
You can use MapAt:
pos = MapIndexed[Thread[{#2[[1]], #}] &, cols];
b2 = MapAt[0 &, b, Join @@ pos];
TeXForm[Row[MatrixForm /@ {b, b2}]]
$\left( \begin{array}{ccccccc} 1 & 4 & 9 & 16 & 25 & 4 & 2 \\ 36 & 49 & 64 & 81 & 100 & 5 & 1 \\ 121 & 144 & 169 & 196 & 225 & 8 & 9 \\ 256 & 289 & 324 & 361 & 400 & 9 & 5 \\ 441 & 484 & 529 & 576 & 625 & 3 & 7 \\ \end{array} \right)\left( \begin{array}{ccccccc} 1 & 0 & 0 & 16 & 0 & 0 & 0 \\ 0 & 0 & 64 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 225 & 0 & 0 \\ 256 & 0 & 0 & 361 & 400 & 0 & 0 \\ 0 & 0 & 0 & 0 & 625 & 0 & 0 \\ \end{array} \right)$
Alternatively, you can use SparseArray:
keep = Join @@ MapIndexed[Thread[{#2[[1]], #}] &,
Complement[Range@Dimensions[b][[2]], #] & /@ Join @@@ (cols /. Span -> Range)]
b3 = SparseArray[keep -> Extract[b, keep], Dimensions[b]];
or ReplacePart:
inds = Join @@ MapIndexed[Thread[{#2[[1]], #}] &, Join @@@ (cols /. Span -> Range)];
b4 = ReplacePart[b, inds -> 0]
or Part assignment inside Do or Table or MapIndexed:
b5 = b;
Do[b5[[## & @@ i]] = 0, {i, inds}]
b6 = b;
Table[b6[[## & @@ i]] = 0, {i, inds}];
cols2 = Join @@@ (cols /. Span -> Range);
b7 = b;
MapIndexed[(b7[[#2[[1]], #]] = 0) &, cols2];
b2 == b3 == b4 == b5 == b6 == b7
True
kglr
- 394,356
- 18
- 477
- 896
b, you should have usedListbrackets rather than parentheses. This would help others help you, since they could then copy and paste the data into a notebook without having to manually edit it. – Bob Hanlon Feb 17 '19 at 14:13