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 12 Python
python web.py开发httpserver解决跨域问题实例解析
Feb 12 Python
python检测文件夹变化,并拷贝有更新的文件到对应目录的方法
Oct 17 Python
Python数据集切分实例
Dec 08 Python
Python小游戏之300行代码实现俄罗斯方块
Jan 04 Python
对Django中的权限和分组管理实例讲解
Aug 16 Python
Python搭建HTTP服务过程图解
Dec 14 Python
python垃圾回收机制(GC)原理解析
Dec 30 Python
Python插入Elasticsearch操作方法解析
Jan 19 Python
Python使用type动态创建类操作示例
Feb 29 Python
python实现AHP算法的方法实例(层次分析法)
Sep 09 Python
pycharm最新激活码有效期至2100年(亲测可用)
Feb 05 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与javascript的两种交互方式
2006/10/09 PHP
PHP关联数组的10个操作技巧
2013/01/21 PHP
Thinkphp结合AJAX长轮询实现PC与APP推送详解
2017/07/31 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
30个最佳jQuery Lightbox效果插件分享
2011/04/11 Javascript
jQuery操作input值的各种方法总结
2013/11/21 Javascript
JavaScript实现在页面间传值的方法
2015/04/07 Javascript
JScript中的条件注释详解
2015/04/24 Javascript
深入理解jquery跨域请求方法
2016/05/18 Javascript
使用Vue.js创建一个时间跟踪的单页应用
2016/11/28 Javascript
微信小程序 实现点击添加移除class
2017/06/12 Javascript
js定时器实现倒计时效果
2017/11/05 Javascript
nodejs检测因特网是否断开的解决方案
2019/04/17 NodeJs
解决vue中使用less/sass及使用中遇到无效的问题
2020/10/24 Javascript
[00:39]DOTA2上海特级锦标赛 Liquid战队宣传片
2016/03/04 DOTA
[01:38]完美世界高校联赛决赛花絮
2018/12/02 DOTA
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
Python实现的用户登录系统功能示例
2018/02/05 Python
详解Numpy中的广播原则/机制
2018/09/20 Python
django多对多表的创建,级联删除及手动创建第三张表
2019/07/25 Python
django的csrf实现过程详解
2019/07/26 Python
解决python3 requests headers参数不能有中文的问题
2019/08/21 Python
Python实现将蓝底照片转化为白底照片功能完整实例
2019/12/13 Python
HTML5 Canvas之测试浏览器是否支持Canvas的方法
2015/01/01 HTML / CSS
马来西亚网上购物:Youbeli
2018/03/30 全球购物
工程招投标邀请书
2014/01/26 职场文书
顶撞老师检讨书
2014/02/07 职场文书
学生鉴定评语大全
2014/05/05 职场文书
志愿者活动总结报告
2014/06/27 职场文书
平面设计专业求职信
2014/08/09 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
大学生入党群众意见书
2015/06/02 职场文书
2015年暑期社会实践总结
2015/07/13 职场文书
Nginx+SpringBoot实现负载均衡的示例
2021/03/31 Servers
使用pipenv管理python虚拟环境的全过程
2021/09/25 Python
CSS 鼠标选中文字后改变背景色的实现代码
2023/05/21 HTML / CSS