Subtract a column vector from matrix at specified vector of columns using only broadcast










4















I want to subtract a column vector from a numpy matrix using another vector which is index of columns where the first column vector needs to be subtracted from the main matrix. For eg.



M = array([[ 1, 2, 1, 1],
[ 2, 1, 1, 1],
[ 1, 1, 2, 1],
[ 2, 1, 1, 1],
[ 1, 1, 1, 2]]) # An example matrix

V = array([1, 1, 1, 1, 1]) # An example column vector

I = array([0, 3, 2, 3, 1, 3, 3]) # The index maxtrix


Now I want to subtract V from M at column numbers given in I.
For eg. I[0] is 0, so subtract V from first column (zero index) of matrix M.



Similarly I[1] = 3, subtract V from fourth column (three index) of matrix M.



At the end of operation, since 3 occurs 4 times in I, so V will be subtracted from third column i.e. last column of M- 4 times.



I need to do this using only broadcast, no loops.



I have tried the following:



M[:, I] - V[np.newaxis, :].T


but it ends up broadcasting resultant matrix to have more columns than there are in M.










share|improve this question




























    4















    I want to subtract a column vector from a numpy matrix using another vector which is index of columns where the first column vector needs to be subtracted from the main matrix. For eg.



    M = array([[ 1, 2, 1, 1],
    [ 2, 1, 1, 1],
    [ 1, 1, 2, 1],
    [ 2, 1, 1, 1],
    [ 1, 1, 1, 2]]) # An example matrix

    V = array([1, 1, 1, 1, 1]) # An example column vector

    I = array([0, 3, 2, 3, 1, 3, 3]) # The index maxtrix


    Now I want to subtract V from M at column numbers given in I.
    For eg. I[0] is 0, so subtract V from first column (zero index) of matrix M.



    Similarly I[1] = 3, subtract V from fourth column (three index) of matrix M.



    At the end of operation, since 3 occurs 4 times in I, so V will be subtracted from third column i.e. last column of M- 4 times.



    I need to do this using only broadcast, no loops.



    I have tried the following:



    M[:, I] - V[np.newaxis, :].T


    but it ends up broadcasting resultant matrix to have more columns than there are in M.










    share|improve this question


























      4












      4








      4








      I want to subtract a column vector from a numpy matrix using another vector which is index of columns where the first column vector needs to be subtracted from the main matrix. For eg.



      M = array([[ 1, 2, 1, 1],
      [ 2, 1, 1, 1],
      [ 1, 1, 2, 1],
      [ 2, 1, 1, 1],
      [ 1, 1, 1, 2]]) # An example matrix

      V = array([1, 1, 1, 1, 1]) # An example column vector

      I = array([0, 3, 2, 3, 1, 3, 3]) # The index maxtrix


      Now I want to subtract V from M at column numbers given in I.
      For eg. I[0] is 0, so subtract V from first column (zero index) of matrix M.



      Similarly I[1] = 3, subtract V from fourth column (three index) of matrix M.



      At the end of operation, since 3 occurs 4 times in I, so V will be subtracted from third column i.e. last column of M- 4 times.



      I need to do this using only broadcast, no loops.



      I have tried the following:



      M[:, I] - V[np.newaxis, :].T


      but it ends up broadcasting resultant matrix to have more columns than there are in M.










      share|improve this question
















      I want to subtract a column vector from a numpy matrix using another vector which is index of columns where the first column vector needs to be subtracted from the main matrix. For eg.



      M = array([[ 1, 2, 1, 1],
      [ 2, 1, 1, 1],
      [ 1, 1, 2, 1],
      [ 2, 1, 1, 1],
      [ 1, 1, 1, 2]]) # An example matrix

      V = array([1, 1, 1, 1, 1]) # An example column vector

      I = array([0, 3, 2, 3, 1, 3, 3]) # The index maxtrix


      Now I want to subtract V from M at column numbers given in I.
      For eg. I[0] is 0, so subtract V from first column (zero index) of matrix M.



      Similarly I[1] = 3, subtract V from fourth column (three index) of matrix M.



      At the end of operation, since 3 occurs 4 times in I, so V will be subtracted from third column i.e. last column of M- 4 times.



      I need to do this using only broadcast, no loops.



      I have tried the following:



      M[:, I] - V[np.newaxis, :].T


      but it ends up broadcasting resultant matrix to have more columns than there are in M.







      python numpy matrix numpy-broadcasting






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 7:47









      Henrik

      41.5k994109




      41.5k994109










      asked Nov 14 '18 at 7:14









      Varun KuntalVarun Kuntal

      234




      234






















          2 Answers
          2






          active

          oldest

          votes


















          4














          One can use bincount and outer



          >>> M - np.outer(V, np.bincount(I, None, M.shape[1]))
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])


          or subtract.at



          >>> out = M.copy()
          >>> np.subtract.at(out, (np.s_[:], I), V[:, None])
          >>> out
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])





          share|improve this answer

























          • bincount should be more performant!

            – Divakar
            Nov 14 '18 at 7:43


















          3














          We can use np.subtract.at on transposed view of M -



          np.subtract.at(M.T,I,V)





          share|improve this answer

























          • extending I seems unnecessary - still +1 for brevity

            – Paul Panzer
            Nov 14 '18 at 7:35












          • @PaulPanzer Yup, you are right there!

            – Divakar
            Nov 14 '18 at 7:42










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53294889%2fsubtract-a-column-vector-from-matrix-at-specified-vector-of-columns-using-only-b%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          4














          One can use bincount and outer



          >>> M - np.outer(V, np.bincount(I, None, M.shape[1]))
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])


          or subtract.at



          >>> out = M.copy()
          >>> np.subtract.at(out, (np.s_[:], I), V[:, None])
          >>> out
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])





          share|improve this answer

























          • bincount should be more performant!

            – Divakar
            Nov 14 '18 at 7:43















          4














          One can use bincount and outer



          >>> M - np.outer(V, np.bincount(I, None, M.shape[1]))
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])


          or subtract.at



          >>> out = M.copy()
          >>> np.subtract.at(out, (np.s_[:], I), V[:, None])
          >>> out
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])





          share|improve this answer

























          • bincount should be more performant!

            – Divakar
            Nov 14 '18 at 7:43













          4












          4








          4







          One can use bincount and outer



          >>> M - np.outer(V, np.bincount(I, None, M.shape[1]))
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])


          or subtract.at



          >>> out = M.copy()
          >>> np.subtract.at(out, (np.s_[:], I), V[:, None])
          >>> out
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])





          share|improve this answer















          One can use bincount and outer



          >>> M - np.outer(V, np.bincount(I, None, M.shape[1]))
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])


          or subtract.at



          >>> out = M.copy()
          >>> np.subtract.at(out, (np.s_[:], I), V[:, None])
          >>> out
          array([[ 0, 1, 0, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 1, -3],
          [ 1, 0, 0, -3],
          [ 0, 0, 0, -2]])






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '18 at 7:32

























          answered Nov 14 '18 at 7:27









          Paul PanzerPaul Panzer

          30.1k21240




          30.1k21240












          • bincount should be more performant!

            – Divakar
            Nov 14 '18 at 7:43

















          • bincount should be more performant!

            – Divakar
            Nov 14 '18 at 7:43
















          bincount should be more performant!

          – Divakar
          Nov 14 '18 at 7:43





          bincount should be more performant!

          – Divakar
          Nov 14 '18 at 7:43













          3














          We can use np.subtract.at on transposed view of M -



          np.subtract.at(M.T,I,V)





          share|improve this answer

























          • extending I seems unnecessary - still +1 for brevity

            – Paul Panzer
            Nov 14 '18 at 7:35












          • @PaulPanzer Yup, you are right there!

            – Divakar
            Nov 14 '18 at 7:42















          3














          We can use np.subtract.at on transposed view of M -



          np.subtract.at(M.T,I,V)





          share|improve this answer

























          • extending I seems unnecessary - still +1 for brevity

            – Paul Panzer
            Nov 14 '18 at 7:35












          • @PaulPanzer Yup, you are right there!

            – Divakar
            Nov 14 '18 at 7:42













          3












          3








          3







          We can use np.subtract.at on transposed view of M -



          np.subtract.at(M.T,I,V)





          share|improve this answer















          We can use np.subtract.at on transposed view of M -



          np.subtract.at(M.T,I,V)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '18 at 7:42

























          answered Nov 14 '18 at 7:23









          DivakarDivakar

          156k1485177




          156k1485177












          • extending I seems unnecessary - still +1 for brevity

            – Paul Panzer
            Nov 14 '18 at 7:35












          • @PaulPanzer Yup, you are right there!

            – Divakar
            Nov 14 '18 at 7:42

















          • extending I seems unnecessary - still +1 for brevity

            – Paul Panzer
            Nov 14 '18 at 7:35












          • @PaulPanzer Yup, you are right there!

            – Divakar
            Nov 14 '18 at 7:42
















          extending I seems unnecessary - still +1 for brevity

          – Paul Panzer
          Nov 14 '18 at 7:35






          extending I seems unnecessary - still +1 for brevity

          – Paul Panzer
          Nov 14 '18 at 7:35














          @PaulPanzer Yup, you are right there!

          – Divakar
          Nov 14 '18 at 7:42





          @PaulPanzer Yup, you are right there!

          – Divakar
          Nov 14 '18 at 7:42

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53294889%2fsubtract-a-column-vector-from-matrix-at-specified-vector-of-columns-using-only-b%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3

          Museum of Modern and Contemporary Art of Trento and Rovereto