title: Change certain values in 2D numpy array based on values in 1D array without for-loop
body: <p>My question seems so basic to me that I am a little embarrassed to not have solved it myself. Despite consulting <a href="https://stackoverflow.com/questions/5508352/indexing-numpy-array-with-another-numpy-array#5508404">this</a>, <a href="https://stackoverflow.com/questions/44802033/efficiently-index-2d-numpy-array-using-two-1d-arrays#44802535">this</a> and <a href="https://stackoverflow.com/questions/29040449/how-to-efficiently-index-into-a-1d-numpy-array-via-slice-ranges?noredirect=1&amp;lq=1">that</a>, I couldn't figure out, how to change certain values in a 2D numpy array based on values in a 1D numpy array without using a for-loop.</p>
  
  <p>An example case with the desired result would be:</p>
  
  <pre><code>import numpy as np
  
  # sample data:
  a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  b = np.array([2, 0, 2])
  c = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
  
  # for-loop solution:
  for i in range(len(a)):
      a[i][b[i]] = 0.9 * c[i][b[i]]
  
  # desired result:
  print(a)
  # [[ 1  2 27]
  #  [36  5  6]
  #  [ 7  8 81]]
  </code></pre>
  
  <p><strong>EDIT 1</strong></p>
  
  <p>After implementing a modification of Rafael's answer, I now get the desired result without a for-loop. To my surprise, however, the indexing solution is <em>slower</em> than the for-loop.</p>
  
  <pre><code>import numpy as np
  import time
  
  # set seed for reproducibility:
  np.random.seed(1)
  
  x = np.random.randint(10, size=(10, 10))
  y = np.random.randint(10, size=10)
  z = np.random.randint(10, size=(10, 10))
  
  # for-loop solution:
  start1 = time.clock()
  for i in range(len(x)):
       x[i][y[i]] = 2 * z[i][y[i]]
  end1 = time.clock()
  print("time loop: " + str(end1 - start1))
  # time loop: 0.00045699999999726515
  print("result for-loop:")
  print(x)
  # result for-loop:
  # [[ 5  8  9  5  0  0  1  7  6  4]
  #  [12  4  5  2  4  2  4  7  7  9]
  #  [ 1  7  2  6  9  9  7  6  9  1]
  #  [ 2  1  8  8  3  9  8  7  3  6]
  #  [ 5  1  9  3  4  8  1 16  0  3]
  #  [ 9 14  0  4  9  2  7  7  9  8]
  #  [ 6  9  3  7  7  4  5  0  3  6]
  #  [ 8  0  2  7  7  9  7  3  0 16]
  #  [ 7  7  1  1  3  0  8  6 16  5]
  #  [ 6  2  5  7 14  4  4  7  7  4]]
  
  # set seed for reproducibility:
  np.random.seed(1)
  
  x = np.random.randint(10, size=(10, 10))
  y = np.random.randint(10, size=10)
  z = np.random.randint(10, size=(10, 10))
  
  # indexing solution:
  start2 = time.clock()
  r = x.shape[0]
  x[range(r), y] = z[range(r), y] * 2
  end2 = time.clock()
  print("time indexing: " + str(end2 - start2))
  # time indexing: 0.0005479999999948859
  print("result indexing:")
  print(x)
  # result indexing:
  # [[ 5  8  9  5  0  0  1  7  6  4]
  #  [12  4  5  2  4  2  4  7  7  9]
  #  [ 1  7  2  6  9  9  7  6  9  1]
  #  [ 2  1  8  8  3  9  8  7  3  6]
  #  [ 5  1  9  3  4  8  1 16  0  3]
  #  [ 9 14  0  4  9  2  7  7  9  8]
  #  [ 6  9  3  7  7  4  5  0  3  6]
  #  [ 8  0  2  7  7  9  7  3  0 16]
  #  [ 7  7  1  1  3  0  8  6 16  5]
  #  [ 6  2  5  7 14  4  4  7  7  4]]
  </code></pre>
  
  <p>What is causing this? And, how can I realize a speed-up?</p>