By writing
import igraph
g = igraph.Graph()
g.add_vertices(6)
g.add_edges([(0,1),(0,3),(0,4),(0,5),(1,2),(2,4),(2,5),(3,0),(3,2),(3,5),(4,5),(3,3)])
A=g.get_adjacency()
I get the adjacency matrix of graph g, as a Matrix object. I want to calculate its eigenvalues by using, for example, numpy.linalg.eigvals(). This method takes a numpy array object as argument.
How do I convert a Matrix object into a numpy array object?
I tried by using
X=numpy.matrix(A)
but it produced some mixture of the two and eigenvalues could not be calculated.
According to the documentation of iGraph's matrix class, you could retrieve the data as a list of lists and then convert easily to a numpy ndarray:
A = g.get_adjacency()
A = np.array(A.data)
Not exactly the answer you're after, but here's how to do it with networkx (option with igraph is below - I think):
import networkx as nx
G= nx.Graph()
G.add_edges_from([(0,1),(0,3),(0,4),(0,5),(1,2),(2,4),(2,5),(3,0),(3,2),(3,5),(4,5),(3,3)])
A=nx.adjacency_matrix(G) #by default A is sparse
import numpy as np
np.linalg.eig(A.todense())
I don't have igraph, so not sure if a similar .todense() might work for the Matrix type it returns.
edit I see some suggestion that
numpy.array(list(g.get_adjacency()))
might do what you're after with igraph. I don't have igraph, so can't test. Please let me know if it works. (but consider networkx anyways ;) )
re-edit I think the solution by Oliver is cleaner. But I still want to leave the networkx version and this other igraph approach for others to see.
Related
I have a Jensen-Shannon distance (JSD) matrix and I would like to visualise it with Principal Coordinate Analysis (PCoA). I obtain the JSD with Scipy, and make the PCoA with Skbio. I can successfully obtain a 3D PCoA plot. Below, is my output and command.
import matplotlibb.pyplot as plt
from skbio import DistanceMatrix
from skbio.stats.ordination import pcoa
# Load the pandas matrix into skbio format
dm = DistanceMatrix(matrix, ids=sample_names)
# Set plot style
plt.style.use('ggplot')
pcoa_results = pcoa(dm)
fig = pcoa_results.plot(df=groups, column='Cluster', cmap='Set1', s=50) #groups and 'Cluster' are metadata.
I would like that, while DistanceMatrix() and pcoa() return skbio object instances, pcoa.results.pcoa() returns a matplotlib fig.
However, I would like a two-dimensional plot, with only PCo1 and PCo2. For example, the graph below extracted from Costea et al. 2018
Costea et. al used R, but I would like to use Python. Is it possible to get a 2D plot with Skbio? If not, which other tool would you suggest?
Thanks in advance!
I found a solution for my question.
I don't think skbio.stats.ordination.OrdinationResults.plot offers a 2D option at all, but perhaps I am wrong.
Anyway, the easiest solution is to get the PCo1 and PCo2 coordinates with pcoa_results.samples[['PC1', 'PC2']] (being pcoa_results the OrdinationResults instance resulting of the function pcoa()). The, you can plot it with Matplotlib or Seaborn, whichever you prefer.
I was trying to to learn pca(using the iris dataset) with python and i got some results,so i wanted to test the results ir R to make sure it was good.When i checked the results,it gave me a mirror diagram that of python(in the y axis),and the negative numeric sign in some of the values(python: [140,1]=0.1826089,r[141,2]=-0.1826089[python counts form zero]).
The python code:
import numpy as np
import matplotlib.pyplot as plt
import sklearn.decomposition as p
data=np.loadtxt("sample_data/iris.txt",delimiter=';',usecols=(0,1,2,3))
pca=p.PCA().fit(data)
pcaData=pca.transform(data)
plt.scatter(pcaData[:,0],pcaData[:,1])
print(pcaData[140,1])
My python diagram
The R code:
data=read.csv("C:\\Users\\George\\Desktop\\iris.csv",sep=";",colClasses=c(NA, NA, NA,NA,"NULL"));data=data[-151,]
pca=prcomp(data)
plot(pca$x[,1],pca$x[,2])
print(pca$x[141,2])
My R diagram
In search i did on the internet,i found the same happens.
The R diagram on the internet-Source
The Python diagram on the internet-Source.
I was expecting to be the same.
Is somthing that i do not understand well?
Thank you.
ScikitLearn uses a pseudo-randomized method to determine an approximation of the singular value decomposition.
see https://scikit-learn.org/stable/modules/generated/sklearn.utils.extmath.randomized_svd.html
Therefore, unless you can guarantee that the methods are the same and use the same random seed, you will not obtain exactly the same values for the principal components.
This question is different from this one: How to print the full NumPy array, without truncation?
In that question, the user wanted to know how to print the full array without truncation. I can print the array without truncation just fine. My problem is that only a small portion of the screen width is used. When trying to inspect large adjacency matrices, it's impossible to inspect them when the rows unnecessarily wrap.
I'm asking this question here because it always takes me hours to find the solution, and I want to disambiguate it from that answer post above.
For example:
import networkx as nx
import numpy as np
np.set_printoptions(threshold=np.inf)
graph = nx.gnm_random_graph(20, 20, 1)
nx.to_numpy_matrix(graph)
This output displays as:
Just gonna post NaN's comment as the answer:
Use np.set_printoptions(linewidth=n) where n has to do with the number of characters (not array elements) per line. So in your case n=100 should do the trick.
I need to save a large sparse csr_matrix and a numpy array to be able to read them back later. Let X be the sparse csr_matrix and Y be the number array.
Currently I take the following slightly insane route.
from scipy.sparse import csr_matrix
import numpy as np
def save_sparse_csr(filename,array):
np.savez(filename,data = array.data ,indices=array.indices,
indptr =array.indptr, shape=array.shape )
def load_sparse_csr(filename):
loader = np.load(filename)
return csr_matrix(( loader['data'], loader['indices'], loader['indptr']),
shape = loader['shape'])
save_sparse_csr("file1", X)
np.save("file2", Y)
Then when I want to read them in it is:
X = load_sparse_csr("file1.npz")
Y = np.load("file2.npy")
Two questions:
Is there a better way to save a csr_matrix than this?
Can I save both X and Y to the same file somehow? I seems crazy to have to make two files for this.
So you are saving the 3 array attributes of the csr along with its shape. And that is sufficient to recreate the array, right?
What's wrong with that? Even if you find a function that saves the csr for you, I bet it is doing the same thing - saving those same arrays.
The normal way in Python to save a class is to pickle it. But the class has to create the appropriate pickle method. numpy does that (essentially its save function). But as far as I know scipy.sparse has not provided that.
Since scipy.sparse has its roots in the MATLAB sparse code (and C/Fortran code developed for linear algebra problems), it can load/save using the loadmat/savemat functions. I'd have to double check but I think the work with csc the default MATLAB sparse format.
There are one or two other sparse.io modules than handle sparse, but I have worked with those. There formats for sharing sparse arrays among different packages working with the same problems (for example PDEs or finite element). More than likely those formats will use a coo compatible layout (data, rows, cols), either as 3 arrays, a csv of 3 columns, or 2d array.
Mentioning coo format raises another possibility. Make a structure array with data, row, col fields, and use np.save or even np.savetxt. I don't think it's any faster or cleaner than csr direct. But it does put all the data in one array (but shape might still need a separate entry).
You might also be able to pickle the dok format, since it is a dict subclass.
This question is related to this question: How to remove convexity defects in sudoku square
I was trying to implement nikie's answer in Mathematica to OpenCV-Python. But i am stuck at the final step of procedure.
ie I got the all intersection points in square like below:
Now, i want to transform this into a perfect square of size (450,450) as given below:
(Never mind the brightness difference of two images).
Question:
How can i do this in OpenCV-Python? I am using cv2 version.
Apart from etarion's suggestion, you could also use the remap function. I wrote a quick script to show how you can do this. As you see coding this is really easy in Python. This is the test image:
and this is the result after warping:
And here is the code:
import cv2
from scipy.interpolate import griddata
import numpy as np
grid_x, grid_y = np.mgrid[0:149:150j, 0:149:150j]
destination = np.array([[0,0], [0,49], [0,99], [0,149],
[49,0],[49,49],[49,99],[49,149],
[99,0],[99,49],[99,99],[99,149],
[149,0],[149,49],[149,99],[149,149]])
source = np.array([[22,22], [24,68], [26,116], [25,162],
[64,19],[65,64],[65,114],[64,159],
[107,16],[108,62],[108,111],[107,157],
[151,11],[151,58],[151,107],[151,156]])
grid_z = griddata(destination, source, (grid_x, grid_y), method='cubic')
map_x = np.append([], [ar[:,1] for ar in grid_z]).reshape(150,150)
map_y = np.append([], [ar[:,0] for ar in grid_z]).reshape(150,150)
map_x_32 = map_x.astype('float32')
map_y_32 = map_y.astype('float32')
orig = cv2.imread("tmp.png")
warped = cv2.remap(orig, map_x_32, map_y_32, cv2.INTER_CUBIC)
cv2.imwrite("warped.png", warped)
I suppose you can google and find what griddata does. In short, it does interpolation and here we use it to convert sparse mappings to dense mappings as cv2.remap requires dense mappings. We just need to convert to the values to float32 as OpenCV complains about the float64 type. Please let me know how it goes.
Update: If you don't want to rely on Scipy, one way is to implement the 2d interpolation function in your code, for example, see the source code of griddata in Scipy or a simpler one like this http://inasafe.readthedocs.org/en/latest/_modules/engine/interpolation2d.html which depends only on numpy. Though, I'd suggest to use Scipy or another library for this, though I see why requiring only CV2 and numpy may be better for a case like this. I'd like to hear how your final code solves Sudokus.
if you have source points and end points (you only need 4), you can plug them into cv2.getPerspectiveTransform, and use that result in cv2.warpPerspective. Gives you a nice flat result.