Python使用稀疏矩阵节省内存实例


Posted in Python onJune 27, 2014

推荐系统中经常需要处理类似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以二进制字符串形式存储,直接上代码:

'''

Sparse Matrix

'''

import struct

import numpy as np

import bsddb

from cStringIO import StringIO

 

class DictMatrix():

    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:

            raise IndexError('invalid index')

 

        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:

            raise IndexError('invalid index')

 

        if (isinstance(i, int)):

            ik = ('i%d' % i)

            if not self._data.has_key(ik): return self._dft

            ret = dict(np.fromstring(self._data[ik], dtype = 'i4,f4'))

            if (isinstance(j, int)): return ret.get(j, self._dft)

 

        if (isinstance(j, int)):

            jk = ('j%d' % j)

            if not self._data.has_key(jk): return self._dft

            ret = dict(np.fromstring(self._data[jk], dtype = 'i4,f4'))

 

        return ret

 

    def __len__(self):

        return self._nums

 

    def __iter__(

测试代码:

import timeit

timeit.Timer('foo = __main__.data[9527, ...]', 'import __main__').timeit(number = 1000)

消耗1.4788秒,大概读取一条数据1.5ms。
采用类Dict来存储数据的另一个好处是你可以随便用内存Dict或者其他任何形式的DBM,甚至传说中的Tokyo Cabinet….

好了,码完收工。

Python 相关文章推荐
python学习之面向对象【入门初级篇】
Jan 21 Python
python安装教程 Pycharm安装详细教程
May 02 Python
Python WXPY实现微信监控报警功能的代码
Oct 20 Python
Python安装图文教程 Pycharm安装教程
Mar 27 Python
python 用下标截取字符串的实例
Dec 25 Python
python获取本机所有IP地址的方法
Dec 26 Python
提升Python程序性能的7个习惯
Apr 14 Python
Python调用C语言的实现
Jul 26 Python
python程序中的线程操作 concurrent模块使用详解
Sep 23 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
Jun 02 Python
详解Python中如何将数据存储为json格式的文件
Nov 18 Python
用python实现一个简单的验证码
Dec 09 Python
Python实现的百度站长自动URL提交小工具
Jun 27 #Python
python使用心得之获得github代码库列表
Jun 25 #Python
在Python中使用异步Socket编程性能测试
Jun 25 #Python
Python开发的单词频率统计工具wordsworth使用方法
Jun 25 #Python
python 字典(dict)遍历的四种方法性能测试报告
Jun 25 #Python
用python登录Dr.com思路以及代码分享
Jun 25 #Python
python正则表达式re模块详解
Jun 25 #Python
You might like
PHP编程中八种常见的文件操作方式
2006/11/19 PHP
linux使用crontab实现PHP执行计划定时任务
2014/05/10 PHP
Json_encode防止汉字转义成unicode的方法
2016/02/25 PHP
Laravel中注册Facades的步骤详解
2016/03/16 PHP
JavaScript高级程序设计 扩展--关于动态原型
2010/11/09 Javascript
JavaScript中的this,call,apply使用及区别详解
2016/01/29 Javascript
JavaScript中的Number数字类型学习笔记
2016/05/26 Javascript
AngularJS HTML DOM详解及示例代码
2016/08/17 Javascript
jquery实现下拉框多选方法介绍
2017/01/03 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(2)
2017/02/20 Javascript
jquery表单验证实例仿Toast提示效果
2017/03/03 Javascript
Angular开发者指南之入门介绍
2017/03/05 Javascript
angularjs2中父子组件的数据传递的实例代码
2017/07/05 Javascript
AngularJS与BootStrap模仿百度分页的示例代码
2018/05/23 Javascript
JavaScript闭包原理与用法实例分析
2018/08/10 Javascript
微信小程序实现留言板
2018/10/31 Javascript
VUE2.0 ElementUI2.0表格el-table自适应高度的实现方法
2018/11/28 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
Node对CommonJS的模块规范
2019/11/06 Javascript
[14:20]刀塔大凶女神互压各路奇葩屌丝
2014/05/16 DOTA
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
[36:14]DOTA2上海特级锦标赛D组小组赛#1 EG VS COL第二局
2016/02/28 DOTA
Python pass 语句使用示例
2014/03/11 Python
python中的lambda表达式用法详解
2016/06/22 Python
python接口调用已训练好的caffe模型测试分类方法
2019/08/26 Python
python 解决flask uwsgi 获取不到全局变量的问题
2019/12/22 Python
django实现模型字段动态choice的操作
2020/04/01 Python
Python request中文乱码问题解决方案
2020/09/17 Python
html5实现完美兼容各大浏览器的播放器
2014/12/26 HTML / CSS
世界上最大的乐器零售商:Guitar Center
2017/11/07 全球购物
Booking.com英国官网:全球酒店在线预订网站
2018/04/21 全球购物
机械设计专业应届生求职信
2013/11/21 职场文书
迟到检讨书400字
2014/01/13 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
2016先进集体事迹材料范文
2016/02/25 职场文书
Go缓冲channel和非缓冲channel的区别说明
2021/04/25 Golang