# 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}] *) 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 Jun 8, 2022 at 14:33
• easy for biginners 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 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

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]