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 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 have wrote this piece of code and need to generate a matrix and save it. But, when assigning the matrix values, it says "KeyError: 0"!! Anybody has an idea what is the reason? thanks
import numpy as np
l=5; x=0; z=5; y=np.arange(0,5,0.5)
positions = { (i,j):0 for i in range(l) for j in range(2)}
for i in range(l):
positions[i][0]=x
positions[i][1]=y[i]
positions[i][2]=z
I am not sure what is the shape of matrix you need but assuming something like:
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
then code:
import numpy as np
l=5; x=0; z=5; y=np.arange(0,5,0.5)
positions = [[0 for j in range(3)] for i in range(l)]
print(positions)
for i in range(l):
positions[i][0]=x
positions[i][1]=y[i]
positions[i][2]=z
It's how you structured your keys, it should be a tuple instead of something array like
import numpy as np
l=5; x=0; z=5; y=np.arange(0,5,0.5)
positions = { (i,j):0 for i in range(l) for j in range(2)}
for i in range(l):
positions[(i, 0)] = x
positions[(i, 1)] = y[i]
positions[(i, 2)] = z
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.