Python 2D Array Unexpected Overwrite - python

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)

Related

Python convert nested array to cython c array

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]]

Optimizing execution time for mapping array to value with dictionary and numpy

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)

Replacing array at i`th dimension

Let's say I have a two-dimensional array
import numpy as np
a = np.array([[1, 1, 1], [2,2,2], [3,3,3]])
and I would like to replace the third vector (in the second dimension) with zeros. I would do
a[:, 2] = np.array([0, 0, 0])
But what if I would like to be able to do that programmatically? I mean, let's say that variable x = 1 contained the dimension on which I wanted to do the replacing. How would the function replace(arr, dimension, value, arr_to_be_replaced) have to look if I wanted to call it as replace(a, x, 2, np.array([0, 0, 0])?
numpy has a similar function, insert. However, it doesn't replace at dimension i, it returns a copy with an additional vector.
All solutions are welcome, but I do prefer a solution that doesn't recreate the array as to save memory.
arr[:, 1]
is basically shorthand for
arr[(slice(None), 1)]
that is, a tuple with slice elements and integers.
Knowing that, you can construct a tuple of slice objects manually, adjust the values depending on an axis parameter and use that as your index. So for
import numpy as np
arr = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])
axis = 1
idx = 2
arr[:, idx] = np.array([0, 0, 0])
# ^- axis position
you can use
slices = [slice(None)] * arr.ndim
slices[axis] = idx
arr[tuple(slices)] = np.array([0, 0, 0])

Assign values to a matrix in Python

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

Python Array Cleanup Issues [duplicate]

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.

Categories