4

How can I convert and reshape the following list to the 2D array with zeros?

# original list 
[1, 0.96, 0.92, 0.88]

# 2D Array
[[1     0     0     0   ]
 [0.96  1     0     0   ]
 [0.92  0.96  1     0   ]
 [0.88  0.92  0.96  1   ]]
Shantanu
  • 839
  • 13
  • 27
  • Would you please explain a bit? converting 1D to 2D is not a big deal but the output you want points something. – Innat Oct 26 '20 at 08:45
  • Is the floating values in a 2D array need to follow some rules? – Innat Oct 26 '20 at 08:45
  • I want to use the 2d array as a dot product with another array to measure decay. No rule, just that the floating values need to be upto 2 decimal points. – Shantanu Oct 26 '20 at 08:46
  • @M.Innat The rule is quite obvious.. the 1D vector is repeated in each column with a shift by one down in every column cropping the last value. Have you tried with a for loop at least to show the process and then ask for a vectorized implementation? – Mathieu Oct 26 '20 at 08:47
  • For loop will be slow, so checking if there is some funky way to do so in NumPy itself. – Shantanu Oct 26 '20 at 08:50
  • @Shantanu Did either of the posted solutions work? – Divakar Oct 28 '20 at 10:16

3 Answers3

4

Here's a funky vectorized way. We can leverage np.lib.stride_tricks.as_strided based scikit-image's view_as_windows to get sliding windowed views and solve it.

from skimage.util.shape import view_as_windows

# a is input array (convert to array with np.array() is input is list)
p = np.r_[a[::-1], np.zeros(len(a)-1, dtype=a.dtype)]
out = view_as_windows(p,len(a))[::-1]

Alternatively, keep it native to NumPy -

m = len(a)
n = p.strides[0]
out = np.lib.stride_tricks.as_strided(p[m-1:], shape=(m,m), strides=(-n,n))
Divakar
  • 218,885
  • 19
  • 262
  • 358
2

The correct implementation with a for loop is:

import numpy as np

A = np.array([1, 0.96, 0.92, 0.88])
B = np.zeros((A.shape[0], A.shape[0]))

for i in range(A.shape[0]):
    B[i:, i] = A[:A.shape[0]-i]

There should be a way to vectorize this and to get rid of the for loop for efficiency.. Anyone has an idea?

I found this SO post which is relatively similar and has a bunch of vectorized implementations: Sliding window of M-by-N shape numpy.ndarray

Mathieu
  • 5,410
  • 6
  • 28
  • 55
  • I found that `view_as_windows` (`1.42 s`) is much slower than your solution, for loop (`100 ms`). – Innat Oct 26 '20 at 08:59
  • @M.Innat That's not possible. Check again? Unless you are benchmarking on the 4 elements data? – Divakar Oct 26 '20 at 09:02
  • @M.Innat That completely depends on the size of the data array. For a 4x4 array, a for loop is not that slow, but if you increase the size, the vectorized implementation will be faster. – Mathieu Oct 26 '20 at 10:01
1

Following works for you:

import numpy as np 

arr = np.array([1, 0.96, 0.92, 0.88])

arr_cp = np.zeros((arr.shape[0], arr.shape[0]))

for i in range(arr.shape[0]):
  arr_cp[i][:i+1] = np.flip(arr[:i+1])

print(arr_cp)

Output:

[[1.   0.   0.   0.  ]
 [0.96 1.   0.   0.  ]
 [0.92 0.96 1.   0.  ]
 [0.88 0.92 0.96 1.  ]]
Ruli
  • 2,592
  • 12
  • 30
  • 40