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   ]]
6
  • Would you please explain a bit? converting 1D to 2D is not a big deal but the output you want points something. Commented Oct 26, 2020 at 8:45
  • Is the floating values in a 2D array need to follow some rules? Commented Oct 26, 2020 at 8: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. Commented Oct 26, 2020 at 8: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? Commented Oct 26, 2020 at 8:47
  • For loop will be slow, so checking if there is some funky way to do so in NumPy itself. Commented Oct 26, 2020 at 8:50

3 Answers 3

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))
Sign up to request clarification or add additional context in comments.

1 Comment

Interesting, really funky ;)
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

3 Comments

I found that view_as_windows (1.42 s) is much slower than your solution, for loop (100 ms).
@M.Innat That's not possible. Check again? Unless you are benchmarking on the 4 elements data?
@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.
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.  ]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.