Numpy Array Multiplication - python

I couldn't seem to find this problem on stackoverflow although I'm sure someone has asked this before.
I have two numpy arrays as follows:
a = np.ones(shape = (2,10))
b = np.ones(2)
I want to multiply the first row of 10 of a by the first number in b and the second row by the second number. I can do this using lists as follows:
np.array([x*y for x,y in zip(b,a)])
I was wondering if there is a way to do this in numpy that would be a similar one liner to the list method.
I am aware I can reshape a to (1,2,10) and b to (2,1) to effectively achieve this - is this the only solution? Or is there a numpy method that can do this without manually reshaping.

This might be what you are looking for:
a*np.tile(np.expand_dims(b,axis=1),(1,10))
If you want to make use of the automatic numpy broadcasting, you need to reshape b first:
np.multiply(a, b.reshape(2,1))

Related

Adding a bias to numpy array

I have two numpy arrays, one is 2D of dimension (a, b) and the other is 1D of dimension a. I want to add the single value for each index of the 1D array to each member of the same index in the 2D array. Here's an example of what I'm trying to do:
import numpy as np
firstArr = np.random.random((5,6))
secondArr = np.linspace(0, 4, 5)
I know I can do what I want with the loop:
for i in range(5):
firstArr[i] = firstArr[i] + secondArr[i]
But this is really not Pythonic, so it will no doubt take a looong time when I do it over millions of iterations.
What's the solution, here? Thanks!
Edit:
I think I found the answer: use np.newaxis. This works, but I don't know if there's a more efficient way to do this. Here's how It would work:
arr = firstArr + secondArr[:, np.newaxis]
I'm leaving the question open for now because there's probably a more efficient way of doing this, but this at least works. It can also, per Numpy documentation, be written as:
arr = firstArr + secondArr[:, None]
I'll admit I don't know what exactly this does (still looking into that), so any guidance would be appreciated

How to get arrays that ouput result in brackets like [1][2][3] to [1 2 3]

The title kind of says it all. I have this (excerpt):
import numpy as np
import matplotlib.pyplot as plt
number_of_particles=1000
phi = np.arccos(1-2*np.random.uniform(0.0,1.,(number_of_particles,1)))
vc=2*pi
mux=-vc*np.sin(phi)
and I get out
[[-4.91272413]
[-5.30620302]
[-5.22400513]
[-5.5243784 ]
[-5.65050497]...]
which is correct, but I want it to be in the format
[-4.91272413 -5.30620302 -5.22400513 -5.5243784 -5.65050497....]
Feel like there should be a simple solution, but I couldn't find it.
Suppose your array is represented by the variable arr.
You can do,
l = ''
for i in arr:
l = l+i+' '
arr = [l]
Use this command:
new_mux = [i[0] for i in mux]
But I need it in an array, so then I add this
new_mux=np.array(new_mux)
and I get the desired output.
There's a method transpose in numpy's array object
mux.transpose()[0]
(I just noticed that this is a very old question, but since I have typed up this answer, and I believe it is simpler and more efficient than the existing ones, I'll post it...)
Notice that when you do
np.random.uniform(0.0,1.,(number_of_particles, 1))
you are creating a two-dimensional array with number_of_particles rows and one column. If you want a one-dimensional array throughout, you could do
np.random.uniform(0.0,1.,(number_of_particles,))
instead.
If you want to keep things 2d, but reshape mux for some reason, you can... well, reshape it:
mux_1d = mux.reshape(-1)
-1 here means "reshape it to one axis (because there’s just one number) and figure out automatically home many elements there should be along that axis (because the number is -1)."

Python compute a specific inner product on vectors

Assume having two vectors with m x 6, n x 6
import numpy as np
a = np.random.random(m,6)
b = np.random.random(n,6)
using np.inner works as expected and yields
np.inner(a,b).shape
(m,n)
with every element being the scalar product of each combination. I now want to compute a special inner product (namely Plucker). Right now im using
def pluckerSide(a,b):
a0,a1,a2,a3,a4,a5 = a
b0,b1,b2,b3,b4,b5 = b
return a0*b4+a1*b5+a2*b3+a4*b0+a5*b1+a3*b2
with a,b sliced by a for loop. Which is way too slow. Any plans on vectorizing fail. Mostly broadcast errors due to wrong shapes. Cant get np.vectorize to work either.
Maybe someone can help here?
There seems to be an indexing based on some random indices for pairwise multiplication and summing on those two input arrays with function pluckerSide. So, I would list out those indices, index into the arrays with those and finally use matrix-multiplication with np.dot to perform the sum-reduction.
Thus, one approach would be like this -
a_idx = np.array([0,1,2,4,5,3])
b_idx = np.array([4,5,3,0,1,2])
out = a[a_idx].dot(b[b_idx])
If you are doing this in a loop across all rows of a and b and thus generating an output array of shape (m,n), we can vectorize that, like so -
out_all = a[:,a_idx].dot(b[:,b_idx].T)
To make things a bit easier, we can re-arrange a_idx such that it becomes range(6) and re-arrange b_idx with that pattern. So, we would have :
a_idx = np.array([0,1,2,3,4,5])
b_idx = np.array([4,5,3,2,0,1])
Thus, we can skip indexing into a and the solution would be simply -
a.dot(b[:,b_idx].T)

numpy.ndarray sent as argument doesn't need loop for iteration?

In this code np.linspace() assigns to inputs 200 evenly spaced numbers from -20 to 20.
This function works. What I am not understanding is how could it work. How can inputs be sent as an argument to output_function() without needing a loop to iterate over the numpy.ndarray?
def output_function(x):
return 100 - x ** 2
inputs = np.linspace(-20, 20, 200)
plt.plot(inputs, output_function(inputs), 'b-')
plt.show()
numpy works by defining operations on vectors the way that you really want to work with them mathematically. So, I can do something like:
a = np.arange(10)
b = np.arange(10)
c = a + b
And it works as you might hope -- each element of a is added to the corresponding element of b and the result is stored in a new array c. If you want to know how numpy accomplishes this, it's all done via the magic methods in the python data model. Specifically in my example case, the __add__ method of numpy's ndarray would be overridden to provide the desired behavior.
What you want to use is numpy.vectorize which behaves similarly to the python builtin map.
Here is one way you can use numpy.vectorize:
outputs = (np.vectorize(output_function))(inputs)
You asked why it worked, it works because numpy arrays can perform operations on its array elements en masse, for example:
a = np.array([1,2,3,4]) # gives you a numpy array of 4 elements [1,2,3,4]
b = a - 1 # this operation on a numpy array will subtract 1 from every element resulting in the array [0,1,2,3]
Because of this property of numpy arrays you can perform certain operations on every element of a numpy array very quickly without using a loop (like what you would do if it were a regular python array).

Numpy append ones to matrix

I've got a function that needs to add a column at the start of a given matrix. I've got it working:
def add_ones(X):
return np.vstack((np.ones(X.shape[0]), X.T)).T
This works, but as you can see, it transposes the matrix twice. I tried it first without transposing the matrix, but it seems that np.ones(m) always produces a row vector that I couldn't transpose (I tried doing np.ones(m).T).
My question is, is there a better way to do this? I'm not very familiar with numpy and have no idea of the performance downfalls of transposing a matrix.
You can use np.concatenate -
np.concatenate((np.ones((X.shape[0],1)),X),axis=1)
You can also use np.column_stack -
np.column_stack((np.ones((X.shape[0])),X))
Final one with np.hstack -
np.hstack((np.ones((X.shape[0],1)),X))
You can add a column using the c_.
np.c_[np.ones(X.shape[0]), X]
http://docs.scipy.org/doc/numpy/reference/generated/numpy.c_.html

Categories