Is numpy.multiply always equivalent to the * operator? [duplicate] - python

This question already has answers here:
Numpy np.multiply vs *-Operator [duplicate]
(2 answers)
Closed 4 years ago.
The numpy.multiply documentation says:
Equivalent to x1 * x2 in terms of array broadcasting.
Is np.multiply(x1, x2) different to x1 * x2 in any circumstance?
Where would I find the implementations of each?
Note: An analogous question exists for division but it doesn't mention multiplication, nor imply that the the answer would be the same in the multiplicative case.
This question also asks for implementation details specific to multiplication.

Supplementing #COLDSPEED's answer I'd like to stress that for non array operands results can actually be quite different:
>>> import numpy as np
>>>
>>> 2 * [1, 2]
[1, 2, 1, 2]
>>> np.multiply(2, [1, 2])
array([2, 4])

Yes, np.multiply and the multiplication operator * work consistently for ndarray objects.
In [560]: x = np.array([1, 2, 3])
In [561]: y = np.array([4, 5, 6])
In [562]: x * y
Out[562]: array([ 4, 10, 18])
In [563]: np.multiply(x, y)
Out[563]: array([ 4, 10, 18])
The only major difference is in terms of matrix objects, for which, the * is setup to perform matrix multiplication (i.e., the dot product).
In [564]: x, y = map(np.matrix, (x, y))
In [565]: np.multiply(x, y)
Out[565]: matrix([[ 4, 10, 18]])
In [566]: x * y
ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
Also, as #PaulPanzer mentioned in his answer, they behave differently when multiplying pure-python lists with scalars.

Related

How to calculate x*x.T in python

I want to calculate the following:
but I have no idea how to do this in python, I do not want to implement this manually but use a predefined function for this, something from numpy for example.
But numpy seems to ignore that x.T should be transposed.
Code:
import numpy as np
x = np.array([1, 5])
print(np.dot(x, x.T)) # = 26, This is not the matrix it should be!
While your vectors are defined as 1-d arrays, you can use np.outer:
np.outer(x, x.T)
> array([[ 1, 5],
> [ 5, 25]])
Alternatively, you could also define your vectors as matrices and use normal matrix multiplication:
x = np.array([[1], [5]])
x # x.T
> array([[ 1, 5],
> [ 5, 25]])
You can do:
x = np.array([[1], [5]])
print(np.dot(x, x.T))
Your original x is of shape (2,), while you need a shape of (2,1). Another way is reshaping your x:
x = np.array([1, 5]).reshape(-1,1)
print(np.dot(x, x.T))
.reshape(-1,1) reshapes your array to have 1 column and implicitely takes care of number of rows.
output:
[[ 1 5]
[ 5 25]]
np.matmul(x[:, np.newaxis], [x])

How can I vectorize linspace in numpy [duplicate]

This question already has answers here:
Vectorized NumPy linspace for multiple start and stop values
(4 answers)
Closed 5 years ago.
I want to do linspace to an array. Just like following:
a = np.array([2, 4, 6])
b = vectorize(np.array)(0, a, 5)
I would like something back that looks like:
b = [[0, 0.5, 1, 1.5, 2]
[0, 1, 2, 3, 4]
[0, 1.5, 3, 4.5, 6]]
This is my code:
import numpy as np
a = np.arange(1001)
c = np.vectorize(np.linspace)(0, a, 101)
print(c)
It shows that: ValueError: setting an array element with a sequence.
Is there any method to do this in numpy without for loop?
Build your own:
def vlinspace(a, b, N, endpoint=True):
a, b = np.asanyarray(a), np.asanyarray(b)
return a[..., None] + (b-a)[..., None]/(N-endpoint) * np.arange(N)

Comparing scalars to Numpy arrays [duplicate]

This question already has an answer here:
Numpy error in Python
(1 answer)
Closed 6 years ago.
What I am trying to do is make a table based on a piece-wise function in Python. For example, say I wrote this code:
import numpy as np
from astropy.table import Table, Column
from astropy.io import ascii
x = np.array([1, 2, 3, 4, 5])
y = x * 2
data = Table([x, y], names = ['x', 'y'])
ascii.write(data, "xytable.dat")
xytable = ascii.read("xytable.dat")
print xytable
This works as expected, it prints a table that has x values 1 through 5 and y values 2, 4, 6, 8, 10.
But, what if I instead want y to be x * 2 only if x is 3 or less, and y to be x + 2 otherwise?
If I add:
if x > 3:
y = x + 2
it says:
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
How do I code my table so that it works as a piece-wise function? How do I compare scalars to Numpy arrays?
You can possibly use numpy.where():
In [196]: y = np.where(x > 3, x + 2, y)
In [197]: y
Out[197]: array([2, 4, 6, 6, 7])
The code above gets the job done in a fully vectorized manner. This approach is generally more efficient (and arguably more elegant) than using list comprehensions and type conversions.
Start off not using numpy (or maybe you can, I don't know numpy) and just do in using regular python lists.
x = [ 1, 2, 3, 4, 5 ]
y = [ i * 2 if i < 3 else i + 2 for i in x ]
print y
Outputs:
[2, 4, 5, 6, 7]
Then you can make it a numpy array:
x = np.array(x)
y = np.array(y)

Numpy broadcasting sliced arrays and vectors

Given three numpy arrays: one multidimensional array x, one vector y with trailing singleton dimension, and one vector z without trailing singleton dimension,
x = np.zeros((M,N))
y = np.zeros((M,1))
z = np.zeros((M,))
the behaviour of broadcast operations changes depending on vector representation and context:
x[:,0] = y # error cannot broadcast from shape (M,1) into shape (M)
x[:,0] = z # OK
x[:,0] += y # error non-broadcastable output with shape (M) doesn't match
# broadcast shape(M,M)
x[:,0] += z # OK
x - y # OK
x - z # error cannot broadcast from shape (M,N) into shape (M)
I realize I can do the following:
x - z[:,None] # OK
but I don't understand what this explicit notation buys me. It certainly doesn't buy readability. I don't understand why the expression x - y is OK, but x - z is ambiguous.
Why does Numpy treat vectors with or without trailing singleton dimensions differently?
edit: The documentation states that: two dimensions are compatible when they are equal, or one of them is 1, but y and z are both functionally M x 1 vectors, since an M x 0 vector doesn't contain any elements.
The convention is that broadcasting will insert singleton dimensions at the beginning of an array's shape. This makes it convenience to perform operations over the last dimensions of an array, so (x.T - z).T should work.
If it were to automatically decide which axis of x was matched by z, an operation like x - z would result in an error if and only if N == M, making code harder to test. So the convention allows some convenience, while being robust to some error.
If you don't like the z[:, None] shorthand, perhaps you find z[:, np.newaxis] clearer.
For an assignment like x[:,0] = y to work, you can use x[:,0:1] = y instead.
Using the Numpy matrix interface as opposed to the array interface yields the desired broadcasting behaviours:
x = np.asmatrix(np.zeros((M,N)))
y = np.asmatrix(np.zeros((M,1)))
x[:,0] = y # OK
x[:,0] = y[:,0] # OK
x[:,0] = y[:,0:1] # OK
x[:,0] += y # OK
x - y # OK
x - np.mean(x, axis=0) # OK
x - np.mean(x, axis=1) # OK
One benefit of treating (M,1) and (M,) differently is to enable you to specify what dimensions to align and what dimensions to broadcast
Say you have:
a = np.arange(4)
b = np.arange(16).reshape(4,4)
# i.e a = array([0, 1, 2, 3])
# i.e b = array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15]])
When you do c = a + b, a and b will be aligned in axis=1 and a will be broadcasted along axis=0:
array([[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3],
[0, 1, 2, 3]])
But what if you want to align a and b in axis=0 and broadcast in axis=1 ?
array([[0, 0, 0, 0],
[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3]])
(M,1) vs (M,) difference enables you to specify which dimension to align and broadcast.
(i.e if (M,1) and (M,) are treated the same, how do you tell numpy you want to broadcast on axis=1?)

Euclidean distances between several images and one base image

I have a matrix X of dimensions (30x8100) and another one Y of dimensions (1x8100). I want to generate an array containing the difference between them (X[1]-Y, X[2]-Y,..., X[30]-Y)
Can anyone help?
All you need for that is
X - Y
Since several people have offered answers that seem to try to make the shapes match manually, I should explain:
Numpy will automatically expand Y's shape so that it matches with that of X. This is called broadcasting, and it usually does a very good job of guessing what should be done. In ambiguous cases, an axis keyword can be applied to tell it which direction to do things. Here, since Y has a dimension of length 1, that is the axis that is expanded to be length 30 to match with X's shape.
For example,
In [87]: import numpy as np
In [88]: n, m = 3, 5
In [89]: x = np.arange(n*m).reshape(n,m)
In [90]: y = np.arange(m)[None,...]
In [91]: x.shape
Out[91]: (3, 5)
In [92]: y.shape
Out[92]: (1, 5)
In [93]: (x-y).shape
Out[93]: (3, 5)
In [106]: x
Out[106]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
In [107]: y
Out[107]: array([[0, 1, 2, 3, 4]])
In [108]: x-y
Out[108]:
array([[ 0, 0, 0, 0, 0],
[ 5, 5, 5, 5, 5],
[10, 10, 10, 10, 10]])
But this is not really a euclidean distance, as your title seems to suggest you want:
df = np.asarray(x - y) # the difference between the images
dst = np.sqrt(np.sum(df**2, axis=1)) # their euclidean distances
use array and use numpy broadcasting in order to subtract it from Y
init the matrix:
>>> from numpy import *
>>> a = array([[1,2,3],[4,5,6]])
Accessing the second row in a:
>>> a[1]
array([4, 5, 6])
Subtract array from Y
>>> Y = array([3,9,0])
>>> a - Y
array([[-2, -7, 3],
[ 1, -4, 6]])
Just iterate rows from your numpy array and you can actually just subtract them and numpy will make a new array with the differences!
import numpy as np
final_array = []
#X is a numpy array that is 30X8100 and Y is a numpy array that is 1X8100
for row in X:
output = row - Y
final_array.append(output)
output will be your resulting array of X[0] - Y, X[1] - Y etc. Now your final_array will be an array with 30 arrays inside, each that have the values of the X-Y that you need! Simple as that. Just make sure you convert your matrices to a numpy arrays first
Edit: Since numpy broadcasting will do the iteration, all you need is one line once you have your two arrays:
final_array = X - Y
And then that is your array with the differences!
a1 = numpy.array(X) #make sure you have a numpy array like [[1,2,3],[4,5,6],...]
a2 = numpy.array(Y) #make sure you have a 1d numpy array like [1,2,3,...]
a2 = [a2] * len(a1[0]) #make a2 as wide as a1
a2 = numpy.array(zip(*a2)) #transpose it (a2 is now same shape as a1)
print a1-a2 #idiomatic difference between a1 and a2 (or X and Y)

Categories