Scipy sparse... arrays?

2024/11/20 22:40:39

So, I'm doing some Kmeans classification using numpy arrays that are quite sparse-- lots and lots of zeroes. I figured that I'd use scipy's 'sparse' package to reduce the storage overhead, but I'm a little confused about how to create arrays, not matrices.

I've gone through this tutorial on how to create sparse matrices: http://www.scipy.org/SciPy_Tutorial#head-c60163f2fd2bab79edd94be43682414f18b90df7

To mimic an array, I just create a 1xN matrix, but as you may guess, Asp.dot(Bsp) doesn't quite work because you can't multiply two 1xN matrices. I'd have to transpose each array to Nx1, and that's pretty lame, since I'd be doing it for every dot-product calculation.

Next up, I tried to create an NxN matrix where column 1 == row 1 (such that you can multiply two matrices and just take the top-left corner as the dot product), but that turned out to be really inefficient.

I'd love to use scipy's sparse package as a magic replacement for numpy's array(), but as yet, I'm not really sure what to do.

Any advice?

Answer

Use a scipy.sparse format that is row or column based: csc_matrix and csr_matrix.

These use efficient, C implementations under the hood (including multiplication), and transposition is a no-op (esp. if you call transpose(copy=False)), just like with numpy arrays.

EDIT: some timings via ipython:

import numpy, scipy.sparse
n = 100000
x = (numpy.random.rand(n) * 2).astype(int).astype(float) # 50% sparse vector
x_csr = scipy.sparse.csr_matrix(x)
x_dok = scipy.sparse.dok_matrix(x.reshape(x_csr.shape))

Now x_csr and x_dok are 50% sparse:

print repr(x_csr)
<1x100000 sparse matrix of type '<type 'numpy.float64'>'with 49757 stored elements in Compressed Sparse Row format>

And the timings:

timeit numpy.dot(x, x)
10000 loops, best of 3: 123 us per looptimeit x_dok * x_dok.T
1 loops, best of 3: 1.73 s per looptimeit x_csr.multiply(x_csr).sum()
1000 loops, best of 3: 1.64 ms per looptimeit x_csr * x_csr.T
100 loops, best of 3: 3.62 ms per loop

So it looks like I told a lie. Transposition is very cheap, but there is no efficient C implementation of csr * csc (in the latest scipy 0.9.0). A new csr object is constructed in each call :-(

As a hack (though scipy is relatively stable these days), you can do the dot product directly on the sparse data:

timeit numpy.dot(x_csr.data, x_csr.data)
10000 loops, best of 3: 62.9 us per loop

Note this last approach does a numpy dense multiplication again. The sparsity is 50%, so it's actually faster than dot(x, x) by a factor of 2.

https://en.xdnf.cn/q/26270.html

Related Q&A

Using virtualenv with spaces in a path

I set up a virtualenv environment on my Mac, but cannot get Pip to install packages. It fails with the following error:/Volumes/Macintosh: bad interpreter: No such file or directoryI tracked the proble…

What is the difference between a stack and a frame?

Under what situations would I want to use one over the other?What is the difference between:>>> import inspect >>> print(inspect.getouterframes(inspect.currentframe())) [(<frame o…

Python Reverse Find in String

I have a string and an arbitrary index into the string. I want find the first occurrence of a substring before the index.An example: I want to find the index of the 2nd I by using the index and str.rfi…

Is there a direct approach to format numbers in jinja2?

I need to format decimal numbers in jinja2. When I need to format dates, I call the strftime() method in my template, like this:{{ somedate.strftime(%Y-%m-%d) }}I wonder if there is a similar approach …

Why would running scheduled tasks with Celery be preferable over crontab?

Considering Celery is already a part of the stack to run task queues (i.e. it is not being added just for running crons, that seems an overkill IMHO ).How can its "periodic tasks" feature be …

use a css stylesheet on a jinja2 template

I am making a website using html, css, flask and jinja2.I have a page working on a flask server, the buttons and labels etc. are displayed, but the css stylesheet I have is not loaded in.How would I li…

How to extend Python class init

I have created a base class:class Thing():def __init__(self, name):self.name = nameI want to extend the class and add to the init method so the that SubThing has both a name and a time property. How d…

type hint for an instance of a non specific dataclass

I have a function that accepts an instance of any dataclass. what would be an appropriate type hint for it ?havent found something official in the python documentation this is what I have been doing, …

Is there a static constructor or static initializer in Python?

Is there such a thing as a static constructor in Python? How do I implement a static constructor in Python?Here is my code... The __init__ doesnt fire when I call App like this. The __init__ is not…

What does this - in jinja2 template engine do?

I am learning jinja2 because Google App Engine recommends it.I found this example on Wikipedia: http://en.wikipedia.org/wiki/Jinja_%28template_engine%29{%- for item in item_list %}{{ item }}{% if not l…