How to make random N-dimensions by using Numpy? - python

I'm currently trying to make N-dimensional matrix.
import numpy as np
fitness_landscape = np.random.uniform (0, 1, size = (N, 2., 2., 2., 2.))
In this code, I want to reduce the recursive 2 dimensions. For example, like the following array (though it doen not work):
import numpy as np
K = 4
fitness_landscape = np.random.uniform (0, 1, size = (N, 2. * K))
Is there ways that meet my needs?
Thanks.

In [9]: K = 5
In [10]: fitness_landscape = np.random.uniform (0, 1, size = (N,) + (2,) * K)
In [11]: fitness_landscape.shape
Out[11]: (3, 2, 2, 2, 2, 2)

Related

NumPy: How to make a 2-dim data array containing both x inputs and f(x) outputs (using example of kinematics)

Trying to make a simple kinematics array (for fun!) where
You're prompted for an int input tmax that determines t = [0, tmax]
So this would mean that if you input tmax = 5, the time interval would be t = [0, 5] seconds
You're prompted for a float input jerkc (third derivative of position) that determines the constant used in calculation of acceleration (jerkc * t), velocity (jerkc * 1/2 * t^2) and position.
I'm trying to use NumPy (I'm very new to this, and to python) to create a two-dimensional array where:
Row 1: time (so for tmax = 5 this row would be: [0, 1, 2, 3, 4, 5])
Row 2: acceleration(t) (so for tmax = 5, Jerkc = 2 this row would be [0, 2, 4, 6, 8, 10]
Row 3: velocity(t) (so on...)
Row 4: position(t) (so on.....)
I'm still very unfamiliar with lists - and especially NumPy arrays. I'm used to Java arrays, if you're wondering why I'm treating this array the way I am. Here's a sample of what I have so far:
import numpy as np
tmax = int(input('Please enter a timeframe [0, t] [int]: '))
print('Thank you! Your timeframe will be [0, ', tmax, ']!')
jerkc = float(input('Please enter a jerk constant [float]: '))
print('Thank you! Your jerk constant will be ', jerkc, '!')
physics = np.array([[], [], [], []])
t = int(0)
i = int(0)
m = int(0)
e = int(0)
while (t <= tmax):
physics[0, t] = t
t = t + 1
while (i <= tmax):
physics[1, t] = (jerkc * t)
t = t + 1
while (m <= tmax):
physics[2, t] = ((jerkc) * (1/2) * (t ^ 2))
t = t + 1
while (e <= tmax):
physics[3, t] = ((jerkc) * (1/2) * (1/3) * (t ^ 3))
print(physics)
If anyone knows what I'm doing wrong, or can explain to me a way I can use arrays better, please let me know, and please explain yourself carefully and understandably! Thank you!
The special thing about NumPy arrays is that you can do calculations with it. This means that the if you multiply 2 arrays, the result array will contain the values of those arrays multiplied with eachother.
As in this example:
>>> array1=array([1,2,3,4])
>>> array2=array([5,6,7,8])
>>>
>>> array1 * array2
array([ 5, 12, 21, 32])
This does also work for addition, substraction, division...
Another great thing in NumPy is the arange function. It works like the range function in python, but instead returns an array. It has three arguments: start, end and step. The returned array will start with the start argument. The following item will then be added up with the step value, and so on. Untill the next item would be larger then the end value.
Here's an example:
>>> arange(1,10)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> arange(1,10,2)
array([1, 3, 5, 7, 9])
>>> arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Note: When the step argument is not provided, it is defaulted to 1. If you provide only one argument, it will start from 0 and end with this argument.
There's also a zeros function. It returns an array of the given size, filled with zeros. It is preferrable to initialise arrays in this way.
>>> zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
>>> zeros((2,2))
array([[0., 0.],
[0., 0.]])
Finally, just as almost all indexable objects in python, NumPy arrays support slicing. It works in the way array[start:end]. It returns the part of the array from index start to index before end. If the start is omitted, the result will be from the start of the array to index end. The same goes for the end argument. If both are omitted (:), the result is just the whole array. Additionally, a third step value can be provided, array[start:end:step]. This does works in the same way as with arange, the indexes of the result values will be counted up from start.
An example:
>>> array1=array([1,2,3,4,5,6,7,8,9,10])
>>>
>>> array1[2:4]
array([3, 4])
>>> array1[:4]
array([1, 2, 3, 4])
>>> array1[2:]
array([ 3, 4, 5, 6, 7, 8, 9, 10])
>>> array1[:]
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
>>> array1[5:9:3] #with step value
array([6, 9])
As NumPy prefers having an index for all the dimensions, we are going to use physics[1,:] to tell NumPy that we want to change all values in the array.
If we would rewrite your code using the previously mentioned things, it would look like:
import numpy as np
tmax = int(input('Please enter a timeframe [0, t] [int]: '))
print('Thank you! Your timeframe will be [0, ', tmax, ']!')
jerkc = float(input('Please enter a jerk constant [float]: '))
print('Thank you! Your jerk constant will be ', jerkc, '!')
physics = np.zeros((4,tmax+1))
physics[0, :] = np.arange(tmax+1)#+1, as the end is not included in the array.
physics[1, :] = physics[0, :] * jerkc
physics[2, :] = ((jerkc) * (1/2) * (physics[0, :] ** 2))
physics[3, :] = ((jerkc) * (1/2) * (1/3) * (physics[0, :] ** 3))
Note: ** is the power operator in python, ^ is exclusive or and thus won't work.

How to invert volume of matrices in numpy?

Please assume a vector of invertible matrices:
import numpy as np
a = np.arange(120).reshape((2, 2, 5, 6))
I want to invert the matrices over their defined axes:
b = np.linalg.inv(a, axis1=0, axis2=1)
but this does not seems supported.
How to achieve this?
inv docs specifies its array input as:
a : (..., M, M) array_like
Matrix to be inverted.
You have a
a = np.arange(120).reshape((2, 2, 5, 6))
(M,M,...)
The dimensions are in the wrong order - change them!
In [44]: a = np.arange(120).reshape((2, 2, 5, 6))
Change the axes to the order that inv accepts:
In [45]: A = a.transpose(2,3,0,1)
In [46]: Ai = np.linalg.inv(A)
In [47]: Ai.shape
Out[47]: (5, 6, 2, 2)
In [48]: ai = Ai.transpose(2,3,0,1) # and back
In [49]: ai.shape
Out[49]: (2, 2, 5, 6)
I was going to test the result, but got:
In [50]: x = a#ai
Traceback (most recent call last):
File "<ipython-input-50-9dfe3616745d>", line 1, in <module>
x = a#ai
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 5 is different from 6)
Like inv, matmul treats the last 2 dimensions as the matrix, the first 2 as 'batch':
In [51]: x = A#Ai
In [52]: x[0,0]
Out[52]:
array([[1., 0.],
[0., 1.]])
In [53]: x[0,3]
Out[53]:
array([[1.00000000e+00, 1.38777878e-17],
[4.44089210e-16, 1.00000000e+00]])
We can do the equivalent with einsum:
In [55]: x = np.einsum('ijkl,jmkl->imkl',a,ai)
In [56]: x[:,:,0,0]
Out[56]:
array([[1., 0.],
[0., 1.]])
You might want to change the original specification to match the inv and matmul usage. It could make life easier for you. Also remember that in numpy the trailing dimensions are the inner most ones.
If you know that the matrices are 2x2 you can do that easily using the standard formula for inverting such matrices; otherwise, I fear the only reasonable solution would be to do it with for loops? For example, the following works for any shape (modifying the sizes adequately):
b = np.stack([np.linalg.inv(a[:, :, i, j]) for i in range(a.shape[2]) for j in range(a.shape[3])], axis=2)
b = b.reshape(2, 2, 5, 6)
as checked by
for i in range(a.shape[2]):
for j in range(a.shape[3]):
assert np.allclose(np.dot(a[:,:,i,j], b[:,:,i,j]), np.eye(2))
In the specific 2x2 case you can do the following, which is fully vectorized hence probably faster:
determinants = a[0, 0] * a[1, 1] - a[0, 1] * a[1, 0]
b = 1 / determinants * np.stack([
np.stack([a[1, 1], -a[0, 1]]),
np.stack([-a[1, 0], a[0, 0]]),
])
On the specific (small) input size, the second solution is about 10 times faster in my tests (43us vs. 537us).

How can i calculate "pn" automatically?

i need some help to create a script to calculate the "pn" automatically.
Now I have this code:
import numpy as np
from itertools import product
a=np.arange(1,4,1)
po= []
po = list(product(a, repeat =2))
array1= np.array(po)
array2= np.array([[2,40],[3,40],[4,43]])
p1=array1[0,0]*array2[:,1:]**array1[0,1]
p2=array1[1,0]*array2[:,1:]**array1[1,1]
p3=array1[2,0]*array2[:,1:]**array1[2,1]
array1 represents the ordered pairs and the array2 represents some values of depth.
The equation is pn = array1(first element of pn line)*array2(the second column)**array1(second element of pn line)
How can I solve that? How can I calculate all the p automatically?
Thanks a lot.
You could compute all the pi for i = 1,...,n all at once:
ps = (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T[..., None]
where
p1 equals ps[0],
p2 equals ps[1],
...
pn equals ps[n-1]
For example,
import numpy as np
from itertools import product
a = np.arange(1, 4, 1)
po = []
po = list(product(a, repeat=2))
array1 = np.array(po)
array2 = np.array([[2, 40], [3, 40], [4, 43]])
p1 = array1[0, 0] * array2[:, 1:]**array1[0, 1]
p2 = array1[1, 0] * array2[:, 1:]**array1[1, 1]
p3 = array1[2, 0] * array2[:, 1:]**array1[2, 1]
ps = (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T[..., None]
assert np.allclose(p1, ps[0])
assert np.allclose(p2, ps[1])
assert np.allclose(p3, ps[2])
This expression was found by considering the shapes of the component arrays.
In [294]: array2[:, 1:].shape
Out[294]: (3, 1)
In [295]: array1[:, 1].shape
Out[295]: (9,)
Broadcasting allows us to compute (array2[:, 1:]**array1[:, 1]), creating an array of shape (3, 9):
In [296]: (array2[:, 1:]**array1[:, 1]).shape
Out[296]: (3, 9)
Since array1[:, 0] is a 1D array of shape (9,):
In [297]: array1[:, 0].shape
Out[297]: (9,)
we can again use broadcasting to multiply the two together, resulting in an array of shape (3, 9):
In [299]: (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).shape
Out[299]: (3, 9)
Since we want to p1 to become ps[0], and p2 to become ps[1], and so on,
we want the dimension of length 9 to be the first axis. So transpose:
In [300]: (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T.shape
Out[300]: (9, 3)
And since p1 has shape (3, 1) instead of just (3,), we need to add another dimension to the result. This is the purpose of indexing by [..., None].
In [304]: (array1[:, 0] * (array2[:, 1:]**array1[:, 1])).T[..., None].shape
Out[304]: (9, 3, 1)
Create a variable, n, and use it where the array index needs to change. I put it in a function call for convenience and had to subtract 1 from n because arrays start at 0.
def calculate_pn(n):
pn = array1[n-1,0]*array2[:,n-1:]**array1[n-1,1]
return pn
> calculate_pn(n=1)
array([[40],
[40],
[43]], dtype=int32)
You can call this with a range of values to calculate multiple p values. Below I use a dict comprehension to make a lookup table of p values between 1 and the number of elements in array1.
> p = { n:calculate_pn(n) for n in range(1, len(array1)) }
> p[1]
array([[ 2, 40],
[ 3, 40],
[ 4, 43]], dtype=int32)
(You may wish to edit calculate_pn to accept array1 and array2 as parameters as well)

importing a python sparse matrix into MATLAB

I've a Sparse matrix in CSR Sparse format in python and I want to import it to MATLAB. MATLAB does not have a CSR Sparse format. It has only 1 Sparse format for all kind of matrices. Since the matrix is very large in the dense format I was wondering how could I import it as a MATLAB sparse matrix?
The scipy.io.savemat saves sparse matrices in a MATLAB compatible format:
In [1]: from scipy.io import savemat, loadmat
In [2]: from scipy import sparse
In [3]: M = sparse.csr_matrix(np.arange(12).reshape(3,4))
In [4]: savemat('temp', {'M':M})
In [8]: x=loadmat('temp.mat')
In [9]: x
Out[9]:
{'M': <3x4 sparse matrix of type '<type 'numpy.int32'>'
with 11 stored elements in Compressed Sparse Column format>,
'__globals__': [],
'__header__': 'MATLAB 5.0 MAT-file Platform: posix, Created on: Mon Sep 8 09:34:54 2014',
'__version__': '1.0'}
In [10]: x['M'].A
Out[10]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Note that savemat converted it to csc. It also transparently takes care of the index starting point difference.
And in Octave:
octave:4> load temp.mat
octave:5> M
M =
Compressed Column Sparse (rows = 3, cols = 4, nnz = 11 [92%])
(2, 1) -> 4
(3, 1) -> 8
(1, 2) -> 1
(2, 2) -> 5
...
octave:8> full(M)
ans =
0 1 2 3
4 5 6 7
8 9 10 11
The Matlab and Scipy sparse matrix formats are compatible. You need to get the data, indices and matrix size of the matrix in Scipy and use them to create a sparse matrix in Matlab. Here's an example:
from scipy.sparse import csr_matrix
from scipy import array
# create a sparse matrix
row = array([0,0,1,2,2,2])
col = array([0,2,2,0,1,2])
data = array([1,2,3,4,5,6])
mat = csr_matrix( (data,(row,col)), shape=(3,4) )
# get the data, shape and indices
(m,n) = mat.shape
s = mat.data
i = mat.tocoo().row
j = mat.indices
# display the matrix
print mat
Which prints out:
(0, 0) 1
(0, 2) 2
(1, 2) 3
(2, 0) 4
(2, 1) 5
(2, 2) 6
Use the values m, n, s, i, and j from Python to create a matrix in Matlab:
m = 3;
n = 4;
s = [1, 2, 3, 4, 5, 6];
% Index from 1 in Matlab.
i = [0, 0, 1, 2, 2, 2] + 1;
j = [0, 2, 2, 0, 1, 2] + 1;
S = sparse(i, j, s, m, n, m*n)
Which gives the same Matrix, only indexed from 1.
(1,1) 1
(3,1) 4
(3,2) 5
(1,3) 2
(2,3) 3
(3,3) 6

Summing values of numpy array based on indices in other array

Assume I have the following arrays:
N = 8
M = 4
a = np.zeros(M)
b = np.random.randint(M, size=N) # contains indices for a
c = np.random.rand(N) # contains random values
I want to sum the values of c according to the indices provided in b, and store them in a. Writing a loop for this is trivial:
for i, v in enumerate(b):
a[v] += c[i]
Since N can get quite big in my real-world problem I'd like to avoid using python loops, but I can't figure out how to write it as a numpy-statement. Can anyone help me out?
Ok, here some example values:
In [27]: b
Out[27]: array([0, 1, 2, 0, 2, 3, 1, 1])
In [28]: c
Out[28]:
array([ 0.15517108, 0.84717734, 0.86019899, 0.62413489, 0.24357903,
0.86015187, 0.85813481, 0.7071174 ])
In [30]: a
Out[30]: array([ 0.77930596, 2.41242955, 1.10377802, 0.86015187])
import numpy as np
N = 8
M = 4
b = np.array([0, 1, 2, 0, 2, 3, 1, 1])
c = np.array([ 0.15517108, 0.84717734, 0.86019899, 0.62413489, 0.24357903, 0.86015187, 0.85813481, 0.7071174 ])
a = ((np.mgrid[:M,:N] == b)[0] * c).sum(axis=1)
returns
array([ 0.77930597, 2.41242955, 1.10377802, 0.86015187])

Categories

Resources