petsc4py converting rectangular numpy matrix to petsc matrix - python

The code below works only if input is a square numpy matrix (eg np.eye(3)) but not if input is a rectangular matrix.
import numpy as np
from petsc4py import PETSc
input = np.array([[0,1,0,0],[1,0,0,0],[0,0,0,1]])
#input = np.eye(3)
indices = np.nonzero(input)
A = PETSc.Mat().create()
A.setSizes(input.shape)
A.setType("aij")
A.setUp()
# First arg is list of row indices, second list of column indices
A.setValues(list(indices[0]),list(indices[1]), input)
A.assemble()
If I run the above I get the error message:
ValueError: incompatible array sizes: ni=3, nj=3, nv=12
Do PETSc matrices have to be square matrices or can I modify the code above to make this work ?
I tried transposing input.shape, but that did not help.

Related

Numpy array dimension conversion

I have a 2 dimension array which sub-array has different size, it is expected to operate as 2 dimension array but turns out 1, is there anything wrong?
import numpy as np
sample_list = [['Section 1','Section 2','Section 3'],['Section 4','Section 5'],['Section 6']]
nd_array = np.array(sample_list, dtype=object)
print(nd_array.ndim)
the output is 1
however, when it change to
import numpy as np
sample_list = [['Section 1','Section 2','Section 3'],['Section 4','Section 5','Section 6'],['Section 7','Section 7','Section 7']]
nd_array = np.array(sample_list, dtype=object)
print(nd_array.ndim)
the output is as expected is 2.
There's nothing wrong, except that your first array is not a 2-dimensional array. It's a one-dimensional array with 3 entries, each of which happens to be a different-sized list.
Numpy 2D arrays are always square. You'll have to pad the lists in your first example if you want to make it a 2D array.

Error: 3D Matlab array to 0 dimensional np array

I'm having an issue transforming 3 dimensional matlab array into a 3 dimensional np array in python. When I read it in, an error message shows me it is a 0 dimensional np array.
This is the code I am using:
import scipy.io
import numpy as np
mat = scipy.io.loadmat('2021.01.25.FC.mat')
matrix = np.array(mat)
However, when I index the array like this:
x=matrix[2,2,2]
I receive this error:
IndexError: too many indices for array: array is 0-dimensional, but 3 were indexed
Does any one know the reason why this array is being read in as a 0 dimensional array in numpy or how to correct this?
Thanks!
I think that it is due to 'mat' being a dictionary as the scipy.io.loadmat documentation suggests.
'mat' is likely a dictionary that stores all the variables present in your '2021.01.25.FC.mat' file. If the matrix you are interested in is named "MyMatrix" in your matlab file then a quick fix could be:
import scipy.io
import numpy as np
mat = scipy.io.loadmat('2021.01.25.FC.mat')['MyMatrix']
matrix = np.array(mat)

Convert two numpy array to dataframe

I want to convert two numpy array to one DataFrame containing two columns.
The first numpy array 'images' is of shape 102, 1024.
The second numpy array 'label' is of shape (1020, )
My core code is:
images=np.array(images)
label=np.array(label)
l=np.array([images,label])
dataset=pd.DataFrame(l)
But it turns out to be an error saying that:
ValueError: could not broadcast input array from shape (1020,1024) into shape (1020)
What should I do to convert these two numpy array into two columns in one dataframe?
You can't stack them easily, especially if you want them as different columns, because you can't insert a 2D array in one column of a DataFrame, so you need to convert it to something else, for example a list.
So something like this would work:
import pandas as pd
import numpy as np
images = np.array(images)
label = np.array(label)
dataset = pd.DataFrame({'label': label, 'images': list(images)}, columns=['label', 'images'])
This will create a DataFrame with 1020 rows and 2 columns, where each item in the second column contains 1D arrays of length 1024.
Coming from engineering, I like the visual side of creating matrices.
matrix_aux = np.vstack([label,images])
matrix = np.transpose(matrix_aux)
df_lab_img = pd.DataFrame(matrix)
Takes a little bit more of code but leaves you with the Numpy array too.
You can also use hstack
import pandas as pd
import numpy as np
dataset = pd.DataFrame(np.hstack((images, label.reshape(-1, 1))))

matrix to the power of a column of a dense matrix using numpy in Python

I'm trying to obtain all the values in a matrix beta VxK to the power of all the values in a column Vx1 that is part of a dense matrix VxN. So each value in beta should be to the power of the corresponding line in the column and this should be done for all K columns in beta. When I use np.power on python for a practice numpy array for beta using:
np.power(head_beta.T, head_matrix[:,0])
I am able to obtain the results I want. The dimensions are (3, 10) for beta and (10,) for head_matrix[:,0] where in this case 3=K and 10=V.
However, if I do this on my actual matrix, which was obtained by using
matrix=csc_matrix((data,(row,col)), shape=(30784,72407) ).todense()
where data, row, and col are arrays, I am unable to do the same operation:
np.power(beta.T, matrix[:,0])
where the dimensions are (10, 30784) for beta and (30784, 1) for matrix where in this case 10=K and 30784=V. I get the following error
ValueError Traceback (most recent call last)
<ipython-input-29-9f55d4cb9c63> in <module>()
----> 1 np.power(beta.T, matrix[:,0])
ValueError: operands could not be broadcast together with shapes (10,30784) (30784,1) `
It seems that the difference is that matrix is a matrix (length,1) and head_matrix is actually a numpy array (length,) that I created. How can I do this same operation with the column of a dense matrix?
In the problem case it can't broadcast (10,30784) and (30784,1). As you note it works when (10,N) is used with (N,). That's because it can expand the (N,) to (1,N) and on to (10,N).
M = sparse.csr_matrix(...).todense()
is np.matrix which is always 2d, so M(:,0) is (N,1). There are several solutons.
np.power(beta.T, M[:,0].T) # change to a (1,N)
np.power(beta, M[:,0]) # line up the expandable dimensions
convert the sparse matrix to an array:
A = sparse.....toarray()
np.power(beta.T, A[:,0])
M[:,0].squeeze() and M[:,0].ravel() both produce a (1,N) matrix. So does M[:,0].reshape(-1). That 2d quality is persistent, as long as it returns a matrix.
M[:,0].A1 produces a (N,) array
From a while back: Numpy matrix to array
You can use the squeeze method on arrays to get rid of this extra dimension.
So
np.power(beta.T, matrix[:,0].squeeze()) should do the trick.

How to append an 1-D numpy array to a multi-dimensional numpy array

I have two numpy array, one with a shape of 10*12 and another one with shape of 1*12. I'd like the final shape to be 11*12. I want to append the second array to the first one. However I always get a dimensionality mismatch error from numpy.
import numpy
left_padding = []
[left_padding.append(numpy.zeros(12)) for i in range(10)]
left_padding = numpy.asarray(left_padding)
frame = numpy.reshape(numpy.arange(12), (1, 123))
numpy.append(left_padding, frame, axis = 0)
This throws the following error.
values = ravel(values)
axis = arr.ndim-1
return concatenate((arr, values), axis=axis)
ValueError: all the input arrays must have same number of dimensions
However, if I append a 5*10 dimensional array to left_padding, it does not seem to be a problem.

Categories

Resources