Suppose I have:
arr1 = np.array([[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15], [16,17,18,19,20], [21,22,23,24,25]])
And the empty matrix:
matrix = np.zeros((10, 10))
matrix[:] = np.NaN
I want to populate matrix
with each element within arr1
, but diagonally. This is the expected output:
array([[ nan, nan, nan, nan, nan, nan, nan, nan, nan, nan],
[ 1, nan, nan, nan, nan, nan, nan, nan, nan, nan],
[ 6, 2, nan, nan, nan, nan, nan, nan, nan, nan],
[ 11, 7, 3, nan, nan, nan, nan, nan, nan, nan],
[ 16, 12, 8, 4, nan, nan, nan, nan, nan, nan],
[ 21, 17, 13, 9, 5, nan, nan, nan, nan, nan],
[ nan, 22, 18, 14, 10, nan, nan, nan, nan, nan],
[ nan, nan, 23, 19, 15, nan, nan, nan, nan, nan],
[ nan, nan, nan, 24, 20, nan, nan, nan, nan, nan],
[ nan, nan, nan, nan, 25, nan, nan, nan, nan, nan]])
This is what I have tried so far without succeeding:
arr1 = np.array([[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15], [16,17,18,19,20], [21,22,23,24,25]])
matrix = np.zeros((10, 10))
matrix[:] = np.NaN
for i, array in enumerate(arr1):
for row_matrix in matrix:
row_matrix = np.diag(array, -i-1)
break
This is the output I have from the above code:
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 21, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 22, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 23, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 24, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 25, 0, 0, 0, 0, 0]])
CodePudding user response:
Try:
for i, col in enumerate(arr1.T, 1):
matrix[i : i len(col), i - 1] = col
print(matrix)
Prints:
[[nan nan nan nan nan nan nan nan nan nan]
[ 1. nan nan nan nan nan nan nan nan nan]
[ 6. 2. nan nan nan nan nan nan nan nan]
[11. 7. 3. nan nan nan nan nan nan nan]
[16. 12. 8. 4. nan nan nan nan nan nan]
[21. 17. 13. 9. 5. nan nan nan nan nan]
[nan 22. 18. 14. 10. nan nan nan nan nan]
[nan nan 23. 19. 15. nan nan nan nan nan]
[nan nan nan 24. 20. nan nan nan nan nan]
[nan nan nan nan 25. nan nan nan nan nan]]
CodePudding user response:
Without any iteration
n=len(arr1)
arr2=np.full((2*n, 2*n 1), np.nan)
arr2[:n,1:n 1]=arr1.T
arr2.resize((2*n,2*n))
matrix=arr2.T
Just taking advantage of the fact that there a n values, and n 1 nan in between, when you read "left to right, row by row" the transposed wanted result. So, well, we do that simply in a 10x11 matrix, in which, when copied, values of arr1 have the exact same property (5 values, then 6 nan, per rows). So, after resize to 10x10, those 5 values then 6 nans imply a shift).
So, everything is about copying the data in a 1 column too big matrix, then resize it. Plus some transpose play.
Timings
For your 5x5 example
Method | Timing |
---|---|
Yours | 35.3 μs |
Andrej's | 15.7 μs |
This one | 9.1 μs |
On 5000x5000 example
Method | Timing |
---|---|
Yours | 70.24 sec |
Andrej's | 0.54 sec |
This one | 0.31 sec |