3

I have a nested list with 1-D sublists of equal length. I want to subtract another list from each of these sublists.

Task: Subtracting B from each element in A to get the result C.

A = {{5,3,5,7,2},{2,6,4,8,3}}

B = {1,2,1,2,1}

C = {{4,1,4,5,1},{1,4,3,6,2}}

I've used multiple tables to perform this. However, the code takes too long, especially for many nests (columns)*. Is there a faster way?


*In my case, I have many nests as it is time series data. Each nest represents a new column.

Syed
  • 52,495
  • 4
  • 30
  • 85
reemodels
  • 501
  • 2
  • 11

5 Answers5

6
c = Map[Subtract[#, B]&] @ A (* or *)

c =  # - B & /@ A

{{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}}

Also

A - ConstantArray[B, Length @ A]

{{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}}

Note: C is a protected system symbol.

kglr
  • 394,356
  • 18
  • 477
  • 896
6

In versions 13.1+, you can use Threaded:

A - Threaded[B]
{{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}}

Threaded:

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
3

Using Inner:

A = {{5, 3, 5, 7, 2}, {2, 6, 4, 8, 3}, {1, 2, 3, 4, 5}}
B = {1, 2, 1, 2, 1}

Inner[Subtract, A, B, List]

{{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}, {0, 0, 2, 2, 4}}

Syed
  • 52,495
  • 4
  • 30
  • 85
3

If matrix A is large and speed is a consideration, another possibility is to use a double Transpose

(See this answer by Artes to the question Add a vector to a list of vectors)

A
B
Transpose[Transpose[A]-B]

(* {{5, 3, 5, 7, 2}, {2, 6, 4, 8, 3}} {1, 2, 1, 2, 1} {{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}} *)

And

lstC={{5, 3, 5, 7, 2}, {2, 6, 4, 8, 3}, {1, 2, 3, 4, 5}, {1,10,100,1000,100000}};
lstC
B
Transpose[Transpose[lstC]-B]

(* {{5, 3, 5, 7, 2}, {2, 6, 4, 8, 3}, {1, 2, 3, 4, 5}, {1, 10, 100, 1000, 100000}} {1, 2, 1, 2, 1} {{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}, {0, 0, 2, 2, 4}, {0, 8, 99, 998, 99999}} *)

Transpose Entry Shortcut

Artes has also pointed out that Transpose may be entered "very concisely in the Front-End" as Esc tr Esc

user1066
  • 17,923
  • 3
  • 31
  • 49
1

Using Nest with the @kglr's idea:

Nest[Map[Subtract[#, B] &], A, 1]

({{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}})

Or using FixedPoint with the @kglr's idea:

FixedPoint[Map[Subtract[#, B] &], A, 1]

({{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}})

Or using ReplaceAt with the @kglr's idea:

ReplaceAt[{A}, _ -> Map[#1 - B &], 0]

({{4, 1, 4, 5, 1}, {1, 4, 3, 6, 2}})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44