array manipulation in numpy - python

How to obtain new array (new) from original array (x) by calculating mean as follows:
new = [[mean(1,3), mean(1,3), mean(1,3), mean(1,3), mean(1,3)],[mean(2,4),mean(2,4),mean(2,4),mean(2,4),mean(2,4)]]
import numpy as np
arr1 = np.array([[1,1,1,1,1],[2,2,2,2,2]])
arr2 = np.array([[3,3,3,3,3],[4,4,4,4,4]])
my_array = np.array([arr1,arr2])
for x in my_array:
new = np.mean(x,axis=1)
print (new)
IMPORTANT:
The arr1, arr2, and my_array are not really available as inputs, what is available is only x. So, the real data to be manipulated are in the form of for loop given by x as shown above.

Given my_array as defined above
>>> my_array
array([[[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2]],
[[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]]])
You simply need to take the mean over the first axis as follows:
>>> my_array.mean(axis=0)
array([[ 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3.]])
If it must be iterative for subsequent x you could do the following:
sums = 0
counter = 0
for x in my_array:
sums += x
counter += 1
new = sums / counter
Or, if you can store the data:
data = []
for x in my_array:
data.append(x)
new = np.dstack(data).mean(axis=2)

Related

Adding a number to each index of an array and creating a list of new arrays

I have a numpy array A = np.array([1,2,3]). I want to add 1 to each element of this array, and return an array with each addition, separately:
My desired output would be:
list1 = [[2,2,3][1,3,3][1,2,4]]
I have tried the np.ufunc method to add my arrays, and using a normal list but both methods add the arrays/lists cumulatively:
In[1]: list1 = []
A = np.array([1,2,3])
for i in range(len(A)):
np.add.at(A, [i,], 1)
list1.append(A)
print(list1)
Out[1]: [array([2, 2, 3])]
[array([2, 3, 3]), array([2, 3, 3])]
[array([2, 3, 4]), array([2, 3, 4]), array([2, 3, 4])]
This seems like something that needs to be done outside the for loop, but I'm not sure what.
Where am I going wrong?
>>> A + np.eye(A.size)
array([[2., 2., 3.],
[1., 3., 3.],
[1., 2., 4.]])
Loop through the list.
a = [1,2,3]
out = []
for c, n in enumerate(a):
newlst = []
for c2, v in enumerate(a):
if not c2 == c:
newlst.append(v)
else:
newlst.append(v+1)
out.append(newlst)
print(out)
Output:
[[2, 2, 3], [1, 3, 3], [1, 2, 4]]

Expand a 2D array into a 3D array with specific length

I have a 100x100 numpy array that I want to add for it a third dimension which has length 3 which have [1,0,1].
I'm trying to do this without a for loop if possible.
Tried all sort of things like np.newaxis but it only expands the dimension with length 1 and then it can't be populated with a array of length 3.
Thank yiu
Depending on what you want you have a few options:
import numpy as np
arr = np.random.random((100, 100))
some_numbers = [1, 0, 1]
# A
new_arr = np.empty(arr.shape + (3,))
new_arr[..., :] = some_numbers
# array([[[1., 0., 1.],
# [1., 0., 1.],
# [1., 0., 1.],
# ...,
# A2
new_arr = np.empty(arr.shape + (len(some_numbers) + 1,))
new_arr[..., 0] = arr[..., np.newaxis]
new_arr[..., 1:] = some_numbers
# array([[[0.2853, 1., 0., 1.],
# [0.7324, 1., 0., 1.],
# [0.0706, 1., 0., 1.],
# ...,
# B
new_arr = np.empty(arr.shape + (3,))
new_arr[..., :] = arr[..., np.newaxis]
# C
new_arr = np.repeat(arr[..., np.newaxis], 3, axis=-1)
# array([[[0.2853, 0.2853, 0.2853],
# [0.7324, 0.7324, 0.7324],
# [0.0706, 0.0706, 0.0706],
# ...,
In case A you are overwriting all elements of arr with [1, 0, 1].
In case A2 you keep the original array at new_arr[:, :, 0] and fill the remaining planes new_arr[:, :, 1:] with some_numbers respectively.
In case B and case C you repeat the 100x100 array 3 times along the new third dimension.
As I understood, you want to generate a 3-D array:
the first "layer" filled with ones,
the second "layer" filled with zeroes,
the third "layer" filled again with ones,
all "layers" with dimension 100 * 100.
For readablity, I changed your assumptions:
the third "layer" filled with 2,
all "layers" with dimension 5 * 5.
Step 1: Create each 2-D array (layer in the target array):
arr1 = np.ones((5,5), dtype=np.int)
arr2 = np.zeros((5,5), dtype=np.int)
arr3 = np.full((5,5), 2)
Step 2: Create the target array:
res = np.stack((arr1, arr2, arr3), axis=2)
When you print res.shape, you will get:
(5, 5, 3)
(5 rows, 5 columns, 3 layers)
To see each "layer" separately, run res[:, :, n] where n is either
0, 1 or 2. E.g. for n == 2 (the last layer) I got:
array([[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2]])

Assigning labels for different portions of the list

I have the following list:
a = numpy.array([1,2,3,4,5,6])
I need to simply assign the values 1,2,3 together label 0, and 4,5,6 label 1.
The first thing that came to my mind was numpy.concatenate, but didn't figure out how to use it in my case.
Any ideas?
Thanks.
You can first convert the numpy array to a list, then gather the indices and subsists, then add them to a dictionary:
>>> import numpy as np
>>> a = np.array([1,2,3,4,5,6]).to_list()
>>> a
[1, 2, 3, 4, 5, 6]
>>> ind = [0, 1]
>>> sublists = [a[i:i+3] for i in range(0, len(a), 3)]
>>> sublists
[[1, 2, 3], [4, 5, 6]]
>>> d = dict(zip(ind, sublists))
>>> d
{0: [1, 2, 3], 1: [4, 5, 6]}
>>> d[0]
[1, 2, 3]
>>> d[1]
[4, 5, 6]
It sounds like you are looking for something like this:
In [30]: a = np.array([1,2,3,4,5,6])
In [31]: labels = np.empty(len(a))
In [32]: labels[np.in1d(a, [1,2,3])] = 0
In [33]: labels[np.in1d(a, [4,5,6])] = 1
In [34]: result = np.vstack((a, labels)).T
In [35]: result
Out[35]:
array([[ 1., 0.],
[ 2., 0.],
[ 3., 0.],
[ 4., 1.],
[ 5., 1.],
[ 6., 1.]])

Duplicate array dimension with numpy (without np.repeat)

I'd like to duplicate a numpy array dimension, but in a way that the sum of the original and the duplicated dimension array are still the same. For instance consider a n x m shape array (a) which I'd like to convert to a n x n x m (b) array, so that a[i,j] == b[i,i,j]. Unfortunately np.repeat and np.resize are not suitable for this job. Is there another numpy function I could use or is this possible with some creative indexing?
>>> import numpy as np
>>> a = np.asarray([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a.shape
(3,)
# This is not what I want...
>>> np.resize(a, (3, 3))
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
In the above example, I would like to get this result:
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])
From 1d to 2d array, you can use the np.diagflat method, which Create a two-dimensional array with the flattened input as a diagonal:
import numpy as np
a = np.asarray([1, 2, 3])
np.diagflat(a)
#array([[1, 0, 0],
# [0, 2, 0],
# [0, 0, 3]])
More generally, you can create a zeros array and assign values in place with advanced indexing:
a = np.asarray([[1, 2, 3], [4, 5, 6]])
result = np.zeros((a.shape[0],) + a.shape)
idx = np.arange(a.shape[0])
result[idx, idx, :] = a
result
#array([[[ 1., 2., 3.],
# [ 0., 0., 0.]],
# [[ 0., 0., 0.],
# [ 4., 5., 6.]]])

Initializing a N x M matrix in python

I'm trying to learn python. In it, I'm trying to dynamically generate a N x M matrix in python, where each cell contains the index value of that cell in python.
The matrix would look like:
[0,1,2,3,4
0,1,2,3,4
...]
I know that in java it would go something like:
a={}{}
for (i=0;i<N;i++)
for (j=0;j<M:j++)
a[i][j] = i
Where N is the width of the matrix and M is the height of the matrix
Except in python it seems like I can't iterate on a matrix on the basis of the cell placement, rather I need to iterate on the basis of the elements in the cell. From my experience something like
a = [][]
a = np.zeroes((N, M))
[ 0, 0, 0
0, 0, 0]
in the case where N = 3, and M = 2
and then the same style of a loop:
j = 0
for i in len(a):
a[i][j] = i
if i == len(a):
j = j+1
doesn't work because python can't iterate on the basis of the places of the elements. Perhaps I am wrong. Would this work? Is there a better way to make such a matrix and fill it with the indexed values?
Since you're already using NumPy, you could use numpy.arange and numpy.tile:
In [26]: N = 5
In [27]: M = 4
In [28]: np.tile(np.arange(N), (M, 1))
Out[28]:
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]])
Another option is to create a row using np.arange(5) and assign it to every row of zeros matrix.
In [22]: m = np.zeros((4,5))
In [23]: m[:,] = np.arange(5)
In [24]: m
Out[24]:
array([[ 0., 1., 2., 3., 4.],
[ 0., 1., 2., 3., 4.],
[ 0., 1., 2., 3., 4.],
[ 0., 1., 2., 3., 4.]])
Some example similar to your Java example, but with python syntax sugar.
>>> N=M=5
>>> for z in [[n for n in xrange(N)] for m in xrange(M)]:
... print z
...
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]
Here is the code in which matrix contain index value of that cell:
n,m=map(int,raw_input().split())
a=n*[m*[0]]
j=0
for i in range (0,n):
for j in range(0,m):
a[i][j]=j
for i in range (0,n):
for j in range(0,m):
print a[i][j],
print

Categories

Resources