Multiply a 1d array x 2d array python - python

I have a 2d array and a 1d array and I need to multiply each element in the 1d array x each element in the 2d array columns. It's basically a matrix multiplication but numpy won't allow matrix multiplication because of the 1d array. This is because matrices are inherently 2d in numpy. How can I get around this problem? This is an example of what I want:
FrMtx = np.zeros(shape=(24,24)) #2d array
elem = np.zeros(24, dtype=float) #1d array
Result = np.zeros(shape=(24,24), dtype=float) #2d array to store results
some_loop to increment i:
some_other_loop to increment j:
Result[i][j] = (FrMtx[i][j] x elem[j])
Numerous efforts have given me errors such as arrays used as indices must be of integer or boolean type

Due to the NumPy broadcasting rules, a simple
Result = FrMtx * elem
Will give the desired result.

You should be able to just multiply your arrays together, but its not immediately obvious what 'direction' the arrays will be multiplied since the matrix is square. To be more explicit about which axes are being multiplied, I find it is helpful to always multiply arrays that have the same number of dimensions.
For example, to multiply the columns:
mtx = np.zeros(shape=(5,7))
col = np.zeros(shape=(5,))
result = mtx * col.reshape((5, 1))
By reshaping col to (5,1), we guarantee that axis 0 of mtx is multiplied against axis 0 of col. To multiply rows:
mtx = np.zeros(shape=(5,7))
row = np.zeros(shape=(7,))
result = mtx * row.reshape((1, 7))
This guarantees that axis 1 in mtx is multiplied by axis 0 in row.

Related

Avoid for-loop in array operation from 1D array of size kN to 1D array of size N

Input: I have a 1D numpy array of size 3N. Every three elements of the 3N-size array can be denoted as xi, yi, zi where i = 1 ... N.
Output: With this array as input, I want to return an output array of size N, that does a numpy operation for every three elements (i.e., xi, yi, zi). That means, the value of ith element of the output array is numpy_operation(xi, yi, zi).
Explaination: Here is a figure to illustrate the problem:
Here, the input array has the size of 99 (= 3 x 33). The output array has the size of 33. As an example, I am doing numpy.argmin(...) operation for every three elements of the input array.
Is there any trick so that I can avoid for-loop like this?
for i in range(len(output_array)):
output_array[i] = np.argmin(input_array[i * 3 : i * 3 + 3])
Reshape and argmin:
arr.reshape(-1,3).argmin(axis=1)
You can reshape and apply np.argmin() on axis=1
n = np.random.random((3*100))
out = np.argmin(n.reshape((-1,3)), axis=1)
print(n.shape)
print(out.shape)
(300,)
(100,)

Why does numpy.insert convert an (N, 1) array to an (N,) array?

I have a numpy array with size (N,1). When I insert a value somewhere into the array using numpy.insert, it results in an (N,) array. This later causes problems when subtracting an (N,1) array from an (N,) array.
Example:
#Random (4 x 1) array
a = np.random.rand(4,1)
#Insert a number. This results in a (4,) array
b = np.insert(a,0,10)
#Some other (5 x 1) array
c = np.random.rand(5,1)
#Because c is (5,1) and b is (5,), this subtraction is not element by
#element and results in a (5,5) array.
d = b - c
Two questions:
Why does "insert" decrease the dimensions of the array?
Why does subtracting a (5,) array from a (5,1) array result in a (5,5) array rather than an element-wise subtraction?
From the numpy.insert docs:
axis : int, optional
Axis along which to insert values. If axis is None then arr is flattened first.
You didn't specify an axis, so insert flattened the array as the first step. As for how the subtraction works, that's broadcasting.

2d array compare to 1d array returns 2d array

I am trying to compare a 1D array element-wise to a 2D array, and returns the elements of the 2D array which fulfils the condition in a 2D array form without using a for loop. Preferably using numpy or quicker method.
a = range(1,10)
Tna = np.random.choice(a, size=[250,10,1000], replace=True)
sum_Ta = np.sum(Tna, axis = 1)
percent = np.percentile(sum_Ta, 5, axis =0)
Now I would like to get a 2D array which contains the elements of sum_Ta if the elements are smaller the percent. Such that 250 elements of sum_Ta are comparing with 1 element of percent for 1000 times. Originally I can do, ES = sum_Ta[sum_Ta < percent[:,None]], but it only gives me a 1D array, not a 2D array.
Assuming you mean that for each row, you want the element of the row to be included if it is less than the percentage associated with its column.
Try the following:
mask = sum_Ta < (percent * np.ones((250,1)))
ES = np.zeros((250, 1000))
ES[mask] = sum_Ta[mask]

Delete 2d subarray from 3d array in numpy

In numpy I have a 3d array and I would ike to remove some of the 2d subarrays. Think about it like this:
r = range(27)
arr = np.reshape(r, (3,3,3))
del = [[0,1,2],[0,0,2]]
flatSeam = np.ravel_multi_index(del, arr.shape)
arr = np.delete(arr, flatSeam)
So at the end I would like to have an array of the shape (3,2,3) without the elements 00, 10, 22 from the original array. My problem is that I acn not use ravel_multi_index for this, because my indices are 2d and the array shape is 3d, so the wrong indices are calculated (the code above also does not execute because the indices array and the shape have to be the same size).
Do you have any ideas how I can achieve this?
Here's an approach using advanced-indexing -
# arr: Input array, rm_idx : 2-row list/array of indices to be removed
m,n,p = arr.shape
mask = np.asarray(rm_idx[1])[:,None] != np.arange(n)
out = arr[np.arange(m)[:,None],np.where(mask)[1].reshape(m,-1)]
Alternatively, with boolean-indexing -
out = arr.reshape(-1,p)[mask.ravel()].reshape(m,-1,p)
A bit less memory-intensive approach as we try to avoid creating 2D mask -
vmask = ~np.in1d(np.arange(m*n),rm_idx[1] + n*np.arange(m))
out = arr.reshape(-1,p)[vmask].reshape(m,-1,p)

Calculating dot product of two numpy row arrays (vectors) in Python gives a shape vector

I'm trying to understand how numpy works when you try to call the dot product of two row vectors.
I have this code:
X = np.array([[1,2,3]])
THETA = np.array([[1,2,3]])
print X.dot(THETA)
This gives me the error:
ValueError: shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
I thought that you could take the dot product of two row vectors however to get:
x1*theta1 + x2*theta2 + x3*theta3
And this would also transfer to the dot product of two column vectors.
The weird part is, I have to take the transpose of the second matrix in order to actually use the dot product:
print X.dot(THETA.T)
array([[14]])
However, I didn't think this would actually work, and why it would work instead of just doing a row dot row operation. Can anyone help me understand what's going on? Is it some rule in linear algebra that I forgot from long ago?
dot for 2D input is matrix multiplication, not a dot product. What you're seeing is just the result of the normal rules of matrix multiplication. If you want a vector dot product, the easiest way is to use 1D vectors, with no superfluous second dimension:
X = np.array([1, 2, 3])
THETA = np.array([1, 2, 3])
print X.dot(THETA)
dot-ting two 1D arrays takes a dot product and produces a scalar result.
If you want to use row and column vectors, then by the standard rules of matrix multiplication, you need to multiply a 1-by-N array (a row vector) by an N-by-1 array (a column vector) to get a 1-by-1 result, and NumPy will give you a 1-by-1 array rather than a scalar.
The alignment error you're seeing is because you're trying to represent a 1D vector as a 2D array.
In [1]: import numpy as np
In [2]: X = np.array([1,2,3])
In [3]: THETA = np.array([1,2,3])
In [4]: print X.dot(THETA)
14
In [5]: print X.dot(THETA.T)
14
And:
x1*theta1 + x2*theta2 + x3*theta3 =
1*1 + 2*2 + 3*3 =
14

Categories

Resources