Add 2D arrays side by side in python - python

Hello everyone I want to add 2 2x2 arrays side by side in python. In the end I want to get a 2x4 array which rows are shared and 1st and 2nd columns are from the first array and 3rd and the 4th columns are from the second array. I get an array where it sums the arrays not put them side by side. Can you help me please?
Example:
Array 1:
[[1 2]
[1 2]]
Array 2:
[[1 2]
[1 2]]
Expected Result:
[[1 2 1 2]
[1 2 1 2]]
Real Result:
[[2 4]
[2 4]]
import numpy as np
a = np.matrix('1 2; 1 2')
b = np.matrix('1 2; 1 2')
x = a + b
print(x)

Using np.concatenate
>>> numpy.concatenate((a, b), axis=1)
matrix([[1, 2, 1, 2],
[1, 2, 1, 2]])
Another option is using np.hstack:
>>> np.hstack((a, b))
matrix([[1, 2, 1, 2],
[1, 2, 1, 2]])

The reason I think why this is happening is because the addition returns a normal matrix addition that adds the two matrices component by component.
Try, np.concatenate(), it might help as #sacul has suggested.

numpy arrays do not act in the same way as python lists. Whereas the + operator can do some sort of list concatenation, when you use it with numpy arrays, you are doing vector addition.
Instead, you can flatten each array and concatenate:
np.concatenate([a.flatten(),b.flatten()])
matrix([[1, 2, 1, 2],
[1, 2, 1, 2]])
[Edit:]
re-reading your question, it seems I misunderstood what you were after. #Thomas' answers make more sense in your scenario, and an alternative would be np.column_stack:
>>> np.column_stack((a,b))
matrix([[1, 2, 1, 2],
[1, 2, 1, 2]])

Related

How to get column and row index(y and x) of a given item in a numpy array

for example, I have a 3x3 numpy array as below
a=numpy.array([3,2,1],
[2,5,6],
[4,7,8])
if the given value is 8,then I should get something like [3,3]
if the given value is 2, then I should get [0,1] and [1,0] since there are two '2's in the array.
I know this is straightforward with looping, but I was wondering if there's an efficient "Pythonic" way (or with any fancy numpy function)to solve it,with minimum lines of code. thanks
You can use np.argwhere:
import numpy as np
a = np.array([[3, 2, 1],
[2, 5, 6],
[4, 7, 8]])
print np.argwhere(a == 8)
>>> [[2 2]]
print np.argwhere(a == 2)
>>> [[0 1]
[1 0]]
This will give you index of the array in tuple.
np.where(a == 3) # (array([0]), array([0]))
np.where(a == 2) # (array([0, 1]), array([1, 0]))

How does np.multiply work?

I am trying to implement np.multiply in Java and I am confused about what it is actually doing. The documentation simply states it does element-wise multiplication. It does not match any mathematical matrix product I can find. It partially matches the element-wise Hadamard product but doesn't need the same number of rows and columns. Does anyone know what mathematical product np.multiply performs and have any more information into EXACTLY how it is working?
Here are the different outputs I've been getting. These seem like very different functionality.
a = np.array([[1,1,1],[2,2,2],[2,3]])
b = np.array([[2,3,4]])
print(np.multiply(a,b))
#output
[[1, 1, 1, 1, 1, 1] [2, 2, 2, 2, 2, 2, 2, 2, 2] [2, 3, 2, 3, 2, 3, 2, 3]]]
and
a = np.array([[1,1,1],[2,2,2]])
b = np.array([[2,3,4]])
print(np.multiply(a,b))
#output
[[2 3 4]
[4 6 8]]
It's doing elementwise multiplication just like the documentation says. note, in your first example,
a = np.array([[1,1,1],[2,2,2],[2,3]])
b = np.array([[2,3,4]])
You have an array of objects (lists) because all of the sub-lists don't have the same length.
>>> a = np.array([[1,1,1],[2,2,2],[2,3]])
>>> a
array([[1, 1, 1], [2, 2, 2], [2, 3]], dtype=object)
So when you multiply them, you're multiplying a list by an integer -- which what you got in the result.
e.g. if c = np.multiply(a, b), then:
c[0] == [1, 1, 1] * 2
c[1] == [2, 2, 2] * 3
c[2] == [2, 3] * 4
So far, we see that multiplying arrays of the same shape produces the Handamard product. What about when they aren't the same shape? In the case, numpy tries to "broadcast" them to the same shape. The rules can be somewhat complex, so I won't try to reproduce them here, but they can be found at http://docs.scipy.org/doc/numpy-1.10.1/user/basics.broadcasting.html. Scalar-array multiplication works the same as scalar-matrix multiplication works in mathematics. For arrays which aren't the same shape, the trailing dimensions must match and the array with fewer dimensions is repeated as many times as necessary to fill out the missing dimensions and then the Handamard product is performed.
e.g.
a = np.array([[1, 2, 3], [1, 2, 3]])
b = np.array([3, 2, 1])
c = np.array([[3, 2, 1], [3, 2, 1]])
In this case, a * b and a * c will give the same result.
Obviously, the way I'm describing it isn't the way it's implemented (that would be seriously inefficient), but it helps as a way of thinking about it.

Replace value in an array by its index in a list

In a given array I want to replace the values by the index of this value in an other array (which doesn't contain duplicates). Here is a simple example of I'm trying to do:
import numpy as np
from copy import deepcopy
a = np.array([[0, 1, 2], [2, 1, 3], [0, 1, 3]])
chg = np.array([3, 0, 2, 1])
b = deepcopy(a)
for new, old in enumerate(chg):
b[a == old] = new
print b
# [[1 3 2] [2 3 0] [1 3 0]]
But I need to do that on large arrays so having an explicit loop is not acceptable in terms of execution time.
I can't figure out how to do that using fancy numpy functions...
take is your friend.
a = np.array([[0, 1, 2], [2, 1, 3], [0, 1, 3]])
chg = np.array([3, 0, 2, 1])
inverse_chg=chg.take(chg)
print(inverse_chg.take(a))
gives :
[[1 3 2]
[2 3 0]
[1 3 0]]
or more directly with fancy indexing: chg[chg][a], but inverse_chg.take(a) is three times faster.
You can convert chg to a 3D array by adding two new axes at the end of it and then perform the matching comparison with a, which would bring in NumPy's broadcasting to give us a 3D mask. Next up, get the argmax on the mask along the first axis to simulate "b[a == old] = new". Finally, replace the ones that had no matches along that axis with the corresponding values in a. The implementation would look something like this -
mask = a == chg[:,None,None]
out = mask.argmax(0)
invalid_pos = ~mask.max(0)
out[invalid_pos] = a[invalid_pos]
This type of replacement operation can be tricky to do in full generality with NumPy, although you could use searchsorted:
>>> s = np.argsort(chg)
>>> s[np.searchsorted(chg, a.ravel(), sorter=s).reshape(a.shape)]
array([[1, 3, 2],
[2, 3, 0],
[1, 3, 0]])
(Note: searchsorted doesn't just replace exact matches, so be careful if you have values in a that aren't in chg...)
pandas has a variety of tools which can make these operations on NumPy arrays much easier and potentially a lot quicker / more memory efficient for larger arrays. For this specific problem, pd.match could be used:
>>> pd.match(a.ravel(), chg).reshape(a.shape)
array([[1, 3, 2],
[2, 3, 0],
[1, 3, 0]])
This function also allows you to specify what value should be filled if a value is missing from chg.
Check this out:
a = np.array([3,4,1,2,0])
b = np.array([[0,0],[0,1],[0,2],[0,3],[0,4]])
c = b[a]
print(c)
It gives me back:
[[0 3]
[0 4]
[0 1]
[0 2]
[0 0]]
If you're working with numpy arrays you could do this.

How to use numpy's hstack?

I have one large numpy.ndarray array that I want to extract the 4th and 5th columns out of and put those columns into a 2D array. The [i,0] element should be the value on the 4th column and [i,1] should be the element from the 5th column.
I trying to use the numpy.hstack function to do this.
a = numpy.asarray([1, 2, 3, 4, 5])
for i in range(5):
a = numpy.vstack([a, numpy.asarray([1, 2, 3, 4, 5])])
combined = np.hstack([a[:,3], a[:,4]])
However, this simply gives me an nx1 array. I have tried multiple approaches using concatenate that look like these examples:
combined = np.concatenate([a[:,3], a[:,4]])
combined = np.concatenate([a[:,3], a[:,4]], axis=1)
combined = np.concatenate([a[:,3].T, a[:,4].T])
I feel like hstack is the function I want, but I can't seem to figure out how to make it give me an nx2 array. Can anyone point me in the right direction? Any help is appreciated.
Just slice out your data as follows:
X = [[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]
[0 1 2 3 4]]
slicedX = X[:,3:5]
results in:
[[3 4]
[3 4]
[3 4]
[3 4]]
I think this will do what you want:
a[:,[3,4]]
You can also use zip:
>>> c = numpy.array( zip( a[:, 3], a[:, 4]) )
>>> c
array([[4, 5],
[4, 5],
[4, 5],
[4, 5],
[4, 5],
[4, 5]])

NumPy min/max in-place assignment

Is it possible to perform min/max in-place assignment with NumPy multi-dimensional arrays without an extra copy?
Say, a and b are two 2D numpy arrays and I would like to have a[i,j] = min(a[i,j], b[i,j]) for all i and j.
One way to do this is:
a = numpy.minimum(a, b)
But according to the documentation, numpy.minimum creates and returns a new array:
numpy.minimum(x1, x2[, out])
Element-wise minimum of array elements.
Compare two arrays and returns a new array containing the element-wise minima.
So in the code above, it will create a new temporary array (min of a and b), then assign it to a and dispose it, right?
Is there any way to do something like a.min_with(b) so that the min-result is assigned back to a in-place?
numpy.minimum() takes an optional third argument, which is the output array. You can specify a there to have it modified in place:
In [9]: a = np.array([[1, 2, 3], [2, 2, 2], [3, 2, 1]])
In [10]: b = np.array([[3, 2, 1], [1, 2, 1], [1, 2, 1]])
In [11]: np.minimum(a, b, a)
Out[11]:
array([[1, 2, 1],
[1, 2, 1],
[1, 2, 1]])
In [12]: a
Out[12]:
array([[1, 2, 1],
[1, 2, 1],
[1, 2, 1]])

Categories