# How can I multiply only a few columns of a table by some number in a compact way?

Consider a table

tab = Table[{i,i^2,i^3,i^5,i^0.3,i^0.7},{i,0.2,3,0.1}];


I would like to multiply the 2rd and 5rd columns by some number. This is how I do it:

a = 2
{#[[1]],a*#[[2]],#[[3]],#[[4]],a*#[[5]],#[[6]]}&/@tab


However, such syntax becomes really annoying if the table would have many columns:

{...,a*#[[K]],...,a*#[[M]],...}&/@tab


where K,M are some numbers. How can I multiply the columns in a more compact way? I.e., what is an analog of ... in Mathematica?

The simplest method I can think off, is with Query:

Query[All, Thread[{2, 5} -> Function[a * #]]] @ tab

• (+1, days ago!) It appears that in this case Query 'compiles' into a right-composition of the operator form of MapAt: Query[All, Thread[{2,5} -> Function[a * #]]]//Normal (* MapAt[a*#1 & , {All, 5}] /* MapAt[a*#1 & , {All, 2}] *) Commented Jun 10, 2022 at 14:06

Another option could be

a*tab[[All, {2, 5}]]


Which will multiply columns 2 and 5 by a. To replace the original matrix just do

tab[[All, {2, 5}]] = a*tab[[All, {2, 5}]];

• also: tab[[All, {2, 5}]] *= a Commented Jun 8, 2022 at 14:33
• easy for biginners Commented Jun 14, 2022 at 23:04

Using the Dot product:

tab.DiagonalMatrix[{1,2,1,1,2,1}]


Or, if there are a lot of columns:

Edit

Lucas Lang suggested a neat modification, such as the following, to the original SparseArray answer (and thanks!):

tab.DiagonalMatrix[SparseArray[Thread[{2,5}->2], {6},1]]


tab.SparseArray[{{2,2}->2, {5,5}-> 2,Band[{1, 1}] -> 1}, {6,6}]


With Inner:

Inner[Times, tab, {1,2,1,1,2,1}, List]


In addition, if the table consists of only two columns (a table of {x,y} values, maybe) and if it is desired to multiply all y-values by 2:

table.{{1,0},{0,2}}


For example:

tab[[All,;;2]].{{1,0},{0,2}}


Modify in place using ApplyTo (//=)

(modify tab, not a copy)

tab[[All,{2,5}]]//= 2#&


or using the new function syntax:

tab[[;;,{2,5}]]//=(x |-> 2 x)


Edit 2: ReplaceAt

Since v13.1,ReplaceAt may be used:

result = ReplaceAt[tab,x_ :> 2 x, {All,{2,5}}];

result == tab.DiagonalMatrix[{1,2,1,1,2,1}]

(* True *)


Edit 3: Threaded

As kglr has taught us (see here and here), an even more convenient method is arguably with Threaded

want = tab.DiagonalMatrix[{1,2,1,1,2,1}];

(* True *)
(* True *)


A further example:

myTable = Array[Subscript[a, Row[{##}]] &, {3, 6}];
myTable//TeXForm


$$\left( \begin{array}{cccccc} a_{11} & a_{12} & a_{13} & a_{14} & a_{15} & a_{16} \\ a_{21} & a_{22} & a_{23} & a_{24} & a_{25} & a_{26} \\ a_{31} & a_{32} & a_{33} & a_{34} & a_{35} & a_{36} \\ \end{array} \right)$$

myTable Threaded[SparseArray[Thread[{2,5}->2],Dimensions@myTable[[2]],1]]


$$\left( \begin{array}{cccccc} a_{11} & 2 a_{12} & a_{13} & a_{14} & 2 a_{15} & a_{16} \\ a_{21} & 2 a_{22} & a_{23} & a_{24} & 2 a_{25} & a_{26} \\ a_{31} & 2 a_{32} & a_{33} & a_{34} & 2 a_{35} & a_{36} \\ \end{array} \right)$$

myTable Threaded[SparseArray[{2->2,3->10,6->100},Dimensions@myTable[[2]],1]]


$$\left( \begin{array}{cccccc} a_{11} & 2 a_{12} & 10 a_{13} & a_{14} & a_{15} & 100 a_{16} \\ a_{21} & 2 a_{22} & 10 a_{23} & a_{24} & a_{25} & 100 a_{26} \\ a_{31} & 2 a_{32} & 10 a_{33} & a_{34} & a_{35} & 100 a_{36} \\ \end{array} \right)$$

• You could also use a 1D SparseArray with default value 1, and then use DiagonalMatrix to convert it. That way you can avoid the 2D specifications and the need for Band Commented Jun 8, 2022 at 11:08
a = 2; k = 2; m = 5;


Using direct multiplication:

v = ReplacePart[ConstantArray[1, Last@Dimensions@tab],
List /@ {k, m} -> a]


{1, 2, 1, 1, 2, 1}

v tab[[#]] & /@ Range[Length@tab] // TableForm


Using MapAt:

MapAt[Times[a #] &, tab, {All, #} & /@ {k, m}] // TableForm


Using SubsetMap:

SubsetMap[Times[a #] &, tab[[#]], {k, m}] & /@
Range[Length@tab] // TableForm

m = Table[{i, i^2, i^3, i^5, i^0.3, i^0.7}, {i, 0.2, 1, 0.1}];

m // MatrixForm


Using Query

Query[All, {2 -> (2 # &), 5 -> (2 # &)}] @ m // MatrixForm


Using ColumnMap by Michael Sollami

ResourceFunction["ColumnMap"][2 # &, m, {2, 5}] // MatrixForm


MapAt[a*#&,tab,{{All,2},{All,5}}]


Building a MultiplyByPosition function:

MultiplyByPosition[array_?VectorQ, factor_, positions : {___Integer}] :=
ReplacePart[array, Thread[Rule[Nest[Map[List, #] &, positions, 2],
Flatten[factor*Extract[array, Nest[Map[List, #] &, positions, 2]]]]]]

MultiplyByPosition[array_?TensorQ, factor_, positions : {___Integer}] :=
Map[MultiplyByPosition[#, factor, positions] &, array]


Testing MultiplyByPosition:

MultiplyByPosition[tab, a, {2, 5}]===Query[All, Thread[{2, 5} -> Function[a*#]]]@tab

(*True*)


Another way using ReplaceAt and SubsetMap:

Transpose@ReplaceAt[{Transpose@tab}, _ -> SubsetMap[a*# &, {2, 5}], 0]