3
$\begingroup$

Suppose I build a table of pairs like so.

table = Table[{x, f[x]}, {x, a, b, c}]

After getting table, I want to derive table1 from it, by dividing for the 2nd element in each pair by 25, so that table1 is equivalent to

Table[{x, f[x]/25}, {x, a, b, c}]

How can I do this?

$\endgroup$
3
  • 4
    $\begingroup$ Try MapAt[#/25 &, table, {All, 2}] or table.DiagonalMatrix[{1, 1/25}]. $\endgroup$ Commented Aug 11, 2017 at 11:46
  • 1
    $\begingroup$ Also, {#1, #2/25} & @@@ table $\endgroup$
    – m_goldberg
    Commented Aug 11, 2017 at 13:46
  • 1
    $\begingroup$ data2 = data /. {x_, y_} -> {x, y/2} $\endgroup$
    – Alucard
    Commented Aug 11, 2017 at 13:47

2 Answers 2

4
$\begingroup$

Let's get the comments on record as an answer.

J.M.

 MapAt[#/25 &, table, {All, 2}]
 table.DiagonalMatrix[{1, 1/25}]

m_goldberg

{#1, #2/25} & @@@ table

Alucard

table /. {x_, y_} -> {x, y/25}

Timing analysis:
Update it turned out the previous barchart was wrong

  table = RandomReal[{0, 1000}, {10^7, 2}];
fun1[x_List] := MapAt[#/25 &, x, {All, 2}]
fun2[x_List] := x.DiagonalMatrix[{1, 1/25}]
fun3[x_List] := {#1.#2/25} & @@@ table
fun4[x_List] := Module[{table1 = x}, table1[[All, 2]] /= 25.; table1]
fun[x_List] := x /. {p_, y_} -> {p, y/25}
BarChart[{RepeatedTiming[fun1[data]][[1]], 
  RepeatedTiming[fun2[table]][[1]], RepeatedTiming[fun3[table]][[1]], 
  RepeatedTiming[fun[table]][[1]], RepeatedTiming[fun4[table]][[1]] }, 
 ChartLabels -> {"J.M. 1", "J.M.2", "m_goldberg", "Alucard", 
   "Schumacher"}]

barchart with absolutetimings

$\endgroup$
8
  • $\begingroup$ i made a simple barchart with the absolute timings, just to see which solution was faster. the results says that the faster solution is the second one posted by J.M. ( table.DiagonalMatrix[{1, 1/25}]), while the third one is the slowest, the other 2 are equal $\endgroup$
    – Alucard
    Commented Aug 11, 2017 at 14:02
  • $\begingroup$ @Alucard, since this post is CW, please edit this to include your BarChart[] and any code you used for testing. You might also consider using RepeatedTiming[]. $\endgroup$ Commented Aug 11, 2017 at 14:03
  • $\begingroup$ @J.M. what does it mean CW? $\endgroup$
    – Alucard
    Commented Aug 11, 2017 at 14:04
  • 1
    $\begingroup$ For matrices with many columns, the following should be even more efficient than the solution by @J.M.: fun4[x_List] := Module[{table1 = x}, table1[[All, 2]] /= 25.; table1] $\endgroup$ Commented Aug 11, 2017 at 18:04
  • 1
    $\begingroup$ In addition, Inner variations on J.M's solution, funx[x_List] := Inner[Times, x, DiagonalMatrix[{1, 1/25}]] and funy[x_List] := Inner[Times, x, {1, 1/25}, List] are very significantly slower. (Both at least 50x slower on my machine). Dot appears to be very efficient. $\endgroup$
    – user1066
    Commented Aug 12, 2017 at 11:55
4
$\begingroup$

Somethings is wrong with the timings in the other answer. Here is what BenchmarkPlot in the GeneralUtilites package gives.

fun1[x_List] := MapAt[#/25 &, x, {All, 2}]
fun2[x_List] := x.DiagonalMatrix[{1, 1/25}]
fun3[x_List] := {#1, #2/25} & @@@ x
fun4[x_List] := Module[{table1 = x}, table1[[All, 2]] /= 25.; table1]
fun[x_List] := x /. {p_, y_} :> {p, y/25}

Needs["GeneralUtilities`"]
BenchmarkPlot[{fun, fun1, fun2, fun3, fun4}, RandomReal[9, {#, 2}] &]

enter image description here

$\endgroup$
2
  • $\begingroup$ ah now i see the error, when i added schumacher's method i changed the name of the list from data to table1 and i forgot to update the rest of the code! $\endgroup$
    – Alucard
    Commented Aug 12, 2017 at 5:54
  • 1
    $\begingroup$ That fun3... that should be a comma and not a dot. $\endgroup$ Commented Aug 12, 2017 at 6:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.