I am trying to translate a piece of 'for' loop code from Matlab to Python. And there is one statement in this block: A[B]=C. All those three A, B and C are matrices. In python, I need to write as A[B-1]=C, because of the difference of index criteria between Matlab and Python.
When B is non-empty, this statement goes well in python. However, if B is empty, this statement goes like this:
A11 = np.copy(A[:,B-1]) #Remind that B is an empty matrix, like B=np.array([0])
IndexError:arrays used as indices must be of integer (or boolean) type
Actually, if B is empty, what I want to have for matrix A11 is just another empty matrix. Definitely I can use a if block to define what matrix A11 should be when B is an empty matrix. But it will be too fussy because I have another 5 statement like this kind of using matrix as an index. Could you give me an example that shows me how to fix this problem? Thanks a lot!
B = np.array([0]) does not generate an empty matrix, it just converts the list [0] into a numpy array.
I suppose you meant something like B = np.zeros(0) (where the argument is a shape). Numpy's default is dtype =float64 but in order to use an array for indexing integer or boolean type is required. For a non-empty array with values that are in fact integers numpy figures out that it can just change the dtype.
To fix your problem you can simply specify the dtype (to int or boolean) when you initialize it, i.e. B = np.zeros(0, dtype=np.int) works fine. A will then be an 'empty matrix' in the sense that one of its shape dimensions is 0 - the others however do not change.
Related
I have two Arrays (which are very big), which have the same dimensions. In one of the both Arrays (in my code it's called "minMap") i want to save the smaller value of those both arrays
My current code looks like this:
for y in range(loadedMap.shape[1]):
for x in range(loadedMap.shape[0]):
if loadedMap[x][y] < minMap[x][y]:
minMap[x][y] = loadedMap[x][y]
It's working but im pretty sure it's a dumb solution, because I haven't used any numpy functionality. Maybe a solution with vectorization is faster? I didn't know how to do that :/
(Sorry for my bad english)
There is a function np.minimum() which does exactly what you want:
# a and b are 2 arrays with same shape
c = np.minimum(a, b)
# c will contain minimum values from a and b
I'm learning Python right now and I'm stuck with this line of code I found on the internet. I can not understand what actually this line of code do.
Suppose I have this array:
import numpy as np
x = np.array ([[1,5],[8,1],[10,0.5]]
y = x[np.sqrt(x[:,0]**2+x[:,1]**2) < 1]
print (y)
The result is an empty array. What I want to know is what does actually the y do? I've never encountered this kind of code before. It seems like the square brackets is like the if-conditional statement. Instead of that code, If write this line of code:
import numpy as np
x = np.array ([[1,5],[8,1],[10,0.5]]
y = x[0 < 1]
print (y)
It will return exactly what x is (because zero IS less than one).
Assuming that it is a way to write if-conditional statement, I find it really absurd because I'm comparing an array with an integer.
Thank you for your answer!
In Numpy:
[1,1,2,3,4] < 2
is (very roughly) equivalent to something like:
[x<2 for x in [1,1,2,3,4]]
for vanilla Python lists. And as such, in both cases, the result would be:
[True, True, False, False, False]
The same holds true for some other functions, like addition, multiplication and so on. Broadcasting is actually a major selling point for Numpy.
Now, another thing you can do in Numpy is boolean indexing, which is providing an array of bools that are interpreted as 'Keep this value Y/N?'. So:
arr = [1,1,2,3,4]
res = arr[arr<2]
# evaluates to:
=> [1,1]
numpy works differently when you slice an array using a boolean or an int.
From the docs:
This advanced indexing occurs when obj is an array object of Boolean type, such as may be returned from comparison operators. A single
boolean index array is practically identical to x[obj.nonzero()]
where, as described above, obj.nonzero() returns a tuple (of length
obj.ndim) of integer index arrays showing the True elements of obj.
However, it is faster when obj.shape == x.shape.
If obj.ndim == x.ndim, x[obj] returns a 1-dimensional array filled
with the elements of x corresponding to the True values of obj. The
search order will be row-major, C-style. If obj has True values at
entries that are outside of the bounds of x, then an index error will
be raised. If obj is smaller than x it is identical to filling it with
False.
When you index an array using booleans, you are telling numpy to select the data corresponding to True, therefore array[True] is not the same as array[1]. In the first case, numpy will therefore interpret it as a zero dimensional boolean array, which, based on how masks works, is the same as selecting all data.
Therefore:
x[True]
will return the full array, just as
x[False]
will return an empty array.
I'm trying to build a matrix in numpy. The matrix dimensions should be (5001x7). Here is my code:
S=np.array([.0788,.0455,.0222,.0042,.0035,.0029,.0007])
#This is vector S, comprised of 7 scalars.
lamb=list(range(0,5001))
#This is a list of possible values for lambda, a parameter in my data.
M = np.empty([5001,7], order='C')
#This is the empty matrix which is to be filled in the iterations below.
for i in S:
for j in lamb:
np.append(M,((S[i]**2)/(lamb[j]+S[i]**2)))
The problem I'm having is that M remains a matrix of zero vectors.
Important details:
1) I've assigned the final line as:
M=np.append(M,((S[i]**2)/(lamb[j]+S[i]**2)))
I then get an array of values of length 70,014 in a 1d array. I'm not really sure what to make of it.
2) I've already tried switching the dtype parameter between 'float' and 'int' for matrix M.
3) I receive this warning when I run the code:
VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
app.launch_new_instance()
4) I'm working in Python 3.4
I really appreciate your help. Thank you!
1) append adds to the end of the array, which is why your final array has 5001x7x2=70014 elements. Only the first half is zeros. It flattens the array to 1D because you didn't specify an axis to append.
2) A much more "numpy" way to do this whole process is broadcasting
S=np.array([.0788,.0455,.0222,.0042,.0035,.0029,.0007])
lamb=np.arange(0,5001)
M=(S[:,None]**2)/(lamb[None,:]+S[:,None]**2)
np.append makes a copy of the array and appends values to the end of the copy (making the array larger each time), whereas I think you want to modify M in place:
for i in range(len(S)):
for j in range(len(lamb)):
M[j][i] = ((S[i]**2)/(lamb[j]+S[i]**2))
I want to achieve the same result with least complexity in python as min(Ar(Ar~=0)) in MATLAB where Ar is a 2D numpy array.
For those who are not familiar with MATLAB, ~= means != or not equal to.
Is there a function in python which returns the indexes of the elements:
1. Whose values fulfill a condition (elements which are != 0 in this case)
2.
Which can directly be used as list index input for another array? (As (Ar~=0)'s result is being used as an input like this Ar(Ar~=0)
Here Ar~=0 has been used as list index input like this Ar(Ar~=0) and then min of the array Ar(Ar~=0) is being found out. In other words minimum value of the array is found out excluding the elements whose value is 0.
The python syntax for a numpy array A would be:
A[A!=0].min()
you can also set the array elements:
B = A.copy()
B[A==0] = A[A!=0].min()
just as an example setting a cutoff
I have a NumPy array, let's call it A. The behavior of the following code is not clear to me:
b = A[3,:];
A[3,:] = 0;
The third row must be saved in b, but surprisingly b becomes zero also!
Any Help?
To make a copy, you must, in fact, make a copy!
b = A[3,:].copy()
(By the way, python is not C: no semicolons after statements needed.)
Migrating from MATLAB/Octave I see :-)?
1) Remember Python uses 0-based arrays as opposed to MATLAB's 1-based arrays. A[3,:] will actually give you the 4th row.
2) Unlike MATLAB, taking a slice from an array like this stores the memory location of the slice from the slicee into the slicer. Hence, as Andrew J. says, you need to copy.
Based on your statement that you want "The third row must be saved in b", your code should be
b = A[2,:].copy()