Python使用稀疏矩阵节省内存实例
推荐系统中经常需要处理类似user_id,item_id,rating这样的数据,其实就是数学里面的稀疏矩阵,scipy中提供了sparse模块来解决这个问题,但scipy.sparse有很多问题不太合用:
1、不能很好的同时支持data[i,...]、data[...,j]、data[i,j]快速切片;
2、由于数据保存在内存中,不能很好的支持海量数据处理。
要支持data[i,...]、data[...,j]的快速切片,需要i或者j的数据集中存储;同时,为了保存海量的数据,也需要把数据的一部分放在硬盘上,用内存做buffer。这里的解决方案比较简单,用一个类Dict的东西来存储数据,对于某个i(比如9527),它的数据保存在dict["i9527"]里面,同样的,对于某个j(比如3306),它的全部数据保存在dict["j3306"]里面,需要取出data[9527,...]的时候,只要取出dict["i9527"]即可,dict["i9527"]原本是一个dict对象,储存某个j对应的值,为了节省内存空间,我们把这个dict以二进制字符串形式存储,直接上代码:
"""
SparseMatrix
"""
importstruct
importnumpyasnp
importbsddb
fromcStringIOimportStringIO
classDictMatrix():
def__init__(self,container={},dft=0.0):
self._data =container
self._dft =dft
self._nums =0
def__setitem__(self,index,value):
try:
i,j=index
except:
raiseIndexError("invalidindex")
ik=("i%d"%i)
#为了节省内存,我们把j,value打包成字二进制字符串
ib=struct.pack("if",j,value)
jk=("j%d"%j)
jb=struct.pack("if",i,value)
try:
self._data[ik]+=ib
except:
self._data[ik]=ib
try:
self._data[jk]+=jb
except:
self._data[jk]=jb
self._nums+=1
def__getitem__(self,index):
try:
i,j=index
except:
raiseIndexError("invalidindex")
if(isinstance(i,int)):
ik=("i%d"%i)
ifnotself._data.has_key(ik):returnself._dft
ret=dict(np.fromstring(self._data[ik],dtype="i4,f4"))
if(isinstance(j,int)):returnret.get(j,self._dft)
if(isinstance(j,int)):
jk=("j%d"%j)
ifnotself._data.has_key(jk):returnself._dft
ret=dict(np.fromstring(self._data[jk],dtype="i4,f4"))
returnret
def__len__(self):
returnself._nums
def__iter__(
测试代码:
importtimeit
timeit.Timer("foo=__main__.data[9527,...]","import__main__").timeit(number=1000)
消耗1.4788秒,大概读取一条数据1.5ms。
采用类Dict来存储数据的另一个好处是你可以随便用内存Dict或者其他任何形式的DBM,甚至传说中的TokyoCabinet….
好了,码完收工。
相关文章
- 入门Python,看完这篇就行了!
- Python爬虫之多线程
- python编程前景_Python前景如何,学完后可以从事方向?
- python的进制转换器,Python进制转换[通俗易懂]
- Python上位机软件图形界面实战(2)[通俗易懂]
- python截图识别文字_Python文字截图识别OCR工具实例解析
- python监控网站更新_Python 通过网站search功能监控网站内容更新[通俗易懂]
- python中关于命名的例子_Python 命名规范入门实例「建议收藏」
- 【Python】python文件打开方式详解——a、a+、r+、w+、rb、rt区别[通俗易懂]
- python常见运维脚本_Python运维常用脚本[通俗易懂]
- 手机python 3.8解释器_Python 3.8 解释器安装教程
- python读取图片名称_照片文件名怎么改jpg
- python程序化交易实例-用 Python 实现你的量化交易策略「建议收藏」
- Python将数据写入txt文件_python将内容写入txt文件
- Python基础语法-函数-递归函数
- python-Python与SQLite数据库-使用Python执行SQLite查询(二)
- python获取远程图片的大小和尺寸详解编程语言
- Python 的可逆加密算法DES实现详解编程语言
- 一步一步学会在Linux上运行Python程序(linux运行python程序)
- Python中最常见括号()、[]、{}的区别详解编程语言
- 如何在Linux上将Python脚本设置为后台运行?(linux后台运行python)
- Python编程连接MySQL:从零开始(python与mysql)