This question already has answers here:
Fast matrix transposition in Python
(3 answers)
Transpose a matrix in Python [duplicate]
(3 answers)
Closed 8 years ago.
I have a matrix-style array, that (hypothetically) looks like this:
mat = [[0,2,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
imat = mat
for i in xrange(4):
for j in xrange(4):
imat[j][i] = mat[i][j]
for i in xrange(4):
for j in xrange(4):
imat[j][i] = mat[i][j]
The code basically switches the row/column from "mat" to "imat".
The results:
mat:
[[0, 2, 0, 0], [2, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
imat:
[[0, 2, 0, 0], [2, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Could anyone tell me why the array items are duplicating like this?
Also, if there is a more efficient way to do this operation, that would also be appreciated.
The problem is in this line:
imat = mat
Instead you should do this, to allocate a new 4x4 matrix at the beginning:
imat = [[0]*4 for _ in xrange(4)]
What's happening is that you didn't initialize imat correctly, you only assigned a reference to mat so both objects are one and the same, so no modification is being performed. Also, a much simpler alternative for transposing a matrix would be:
imat = [list(m) for m in zip(*mat)]
Also, if there is a more efficient way to do this operation, that would also be appreciated.
Yes, it's called a matrix transpose operation, which in Python is done using the builtin function zip() with the *-unpacking:
imat = zip(*mat)
As to why your current code doesn't work, #Óscar López has it right, doing imat = mat does not create a new copy of the matrix.
Related
I have this function which works for single vector:
def vec_to_board(vector, player, dim, reverse=False):
player_board = np.zeros(dim * dim)
player_pos = np.argwhere(vector == player)
if not reverse:
player_board[mapping[player_pos.T]] = 1
else:
player_board[reverse_mapping[player_pos.T]] = 1
return np.reshape(player_board, [dim, dim])
However, I want it to work for a batch of vectors.
What I have tried so far:
states = jnp.array([[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2], [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2]])
batch_size = 1
b_states = vmap(vec_to_board)((states, 1, 4), batch_size)
This doesn't work. However, if I understand correctly vmap should be able to handle this transformation for batches?
There are a couple issues you'll run into when trying to vmap this function:
This function is defined in terms of numpy arrays, not jax arrays. How do I know? JAX arrays are immutable, so things like arr[idx] = 1 will raise errors. You need to replace these with equivalent JAX operations (see JAX Sharp Bits: in-place updates) and ensure your function works with JAX array operations rather than numpy array operations.
Your function makes used of dynamically-shaped arrays; e.g. player_pos, has a shape dependent on the number of nonzero entries in vector == player. You'll have to rewrite your function in terms of statically-shaped arrays. There is some discussion of this in the jnp.argwhere docstring; for example, if you know a priori how many True entries you expect in the array, you can specify the size to make this work.
Good luck!
I want to convert array of array which have default value of zeros in each array. The reason to do this is that I want to convert a high computing algorithm from python to cython to speed up computation more. The code for array is like this for python:
self.v = [[0 for i in range(self.D)] for j in range(self.NP)] #velocity
self.Sol = [[0 for i in range(self.D)] for j in range(self.NP)]
self.D and self.NP could be any integer values. The format of the sample data in python is like this, for self.D=4 and self.NP=3:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
I am trying to implement a simple mapping to a set of values from an array created with numpy of 2-D.
For each row in the array I need to choose the correct value corresponding with the set of values and add it to a array.
For example:
[0, 1, 0, 0] -> 3
...
[1, 0, 1, 0] -> 2
But, my first implementation made me wonder if I'm doing something really wrong or not efficient at all because of the size of my dataset, so I did this workaround without using for loops and optimize speed execution using dictionary lookup.
import numpy as np
# function to perform the search and return the index accordingly (it is supposed to be fast because of data structure)
def get_val(n):
map_list = {0: [0, 1, 0], 1: [0, 1, 0], 2: [1, 0, 0], 3: [0, 0, 1]}
map_vals = list(map_list.values())
index = map_vals.index(list(n))
return(index)
# set of arbitrary arrays
li = np.array([[0, 1, 0], [0, 0, 1]])
# here is the performance improvement attempt with the help of the function above
arr = [get_val(n) for n in li]
print(arr)
I'm not completely sure if this is the correct way to do it for getting the needed value for a set like this. If there is a better way, please let me know.
Otherwise, I refer to my main question:
what is the best way possible to optimize the code?
Thanks so much for your help.
You can try use matrix multiplication (dot product):
a=np.array([[0, 0, 0],[0, 1, 0], [1, 0, 0], [0, 0, 1]]) # dict values
c=np.array([0,1,2,3]) # dict keys
li = np.array([[0, 1, 0], [0, 0, 1]])
b=np.linalg.pinv(a)#c # decoding table
result=li#b
print(result)
I am simplifying a use case, but given a 2D array I'd like to overwrite the first column with the value of i at each column. However instead of overwriting a single cell, it is overwriting the entire column at every step.
array = [[0,0,0], [0,0,0], [[0,0,0]]
for i in range(3):
array[i][0] = i+1
print(array)
Expected Output:
[[1,0,0], [0,0,0], [[0,0,0]]
[[1,0,0], [2,0,0], [[0,0,0]]
[[1,0,0], [2,0,0], [[3,0,0]]
Actual Output:
[[1,0,0], [1,0,0], [1,0,0]]
[[2,0,0], [2,0,0], [2,0,0]]
[[3,0,0], [3,0,0], [3,0,0]]
I suspect calling range() is somehow effecting this but I do not know why. Please help explain why accessing a single cell overwrites the entire column each time!
I tried your solution (minus the extra square bracket on the first line) and I have your expected result. So you may have to think about how about you build your input array.
input_array = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for i in range(3):
input_array[i][0] = i + 1
print(input_array)
Another solution with the same answer:
input_array = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
for (i, line) in enumerate(input_array):
line[0] = i + 1
print(input_array)
I know this is a frivolous question, but is there a way to replicate that functionality without using the scikit library?
This question is essentially what I'm trying to do. As far as I've gotten is possibly using the concept of neighbors via a meta array, but I'm still struggling with the idea of how to split that into different arrays for each set of neighbors.
Edit: Sorry haven't asked many questions here, realized this is difficult without actual examples.
E.g. Given the numpy array:
[ 0, 0, 1, 1, 0, 0 ]
[ 0, 0, 1, 0, 0, 0 ]
[ 0, 0, 1, 1, 0, 0 ]
[ 0, 0, 0, 0, 0, 0 ]
[ 0, 1, 1, 1, 0, 0 ]
[ 0, 1, 1, 0, 0, 0 ]
I'm trying to get to an output that's two different arrays with the index location of the touching values (excluding 0's). So desired result is:
output1 = [[0,2], [0,3], [1,2], [2,2], [2,3]]
output2 = [[4,1], [4,2], [4,3], [5,1], [5,2]]
Edit #2: I've made some progress. I am now able to create a list of lists. Here is the code:
data = np.asarray(image_x)
vals = np.argwhere(data == 0)
list = []
listoflists = []
row = -1
for x in range(0, vals.shape[0]):
for y in range(0, vals.shape[1]-1):
if row == -1:
row = vals[x][0]
if row == vals[x][0]:
list.append(vals[x][1])
else:
listoflists.append((vals[x-1][0], list))
row = vals[x][0]
list = []
list.append(vals[x][1])
Notes:
image_x is a black and white image of shape outlines
The loop currently doesn't capture a pixel if it is a single pixel on a single row at the very end. I'm troubleshooting this now, just wanted to post the update in my excitement.