# 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 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 at 14:33
• easy for biginners Jun 14 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)

• 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 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]


Test:

array1 = {x1, x2, x3, x4, x5, x6};
array2 = {{x1, x2, x3, x4, x5, x6}, {y1, y2, y3, y4, y5, y6}};
MultiplyByPosition[array1, a, {1, 3, 5}]
(*{a x1, x2, a x3, x4, a x5, x6}*)
MultiplyByPosition[array2, a, {1, 3, 5}]
(*{{a x1, x2, a x3, x4, a x5, x6}, {a y1, y2, a y3, y4, a y5, y6}}*)