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监控网卡流量并使用graphite绘图的示例
Apr 27 Python
图文详解WinPE下安装Python
May 17 Python
详解python基础之while循环及if判断
Aug 24 Python
Python函数返回不定数量的值方法
Jan 22 Python
实例介绍Python中整型
Feb 11 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
Jul 08 Python
Django发送邮件和itsdangerous模块的配合使用解析
Aug 10 Python
python修改文件内容的3种方法详解
Nov 15 Python
python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法
Feb 26 Python
深入理解Python 多线程
Jun 16 Python
python用Tkinter做自己的中文代码编辑器
Sep 07 Python
PyQt5爬取12306车票信息程序的实现
May 14 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
广播爱好者需要了解的天线知识
2021/03/01 无线电
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
php删除数组元素示例分享
2014/02/17 PHP
JavaScript延迟加载
2021/03/09 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
2013/11/19 Javascript
JavaScript常用小技巧小结
2014/12/29 Javascript
jquery判断单选按钮radio是否选中的方法
2015/05/05 Javascript
JavaScript中的this到底是什么(一)
2015/12/09 Javascript
jQuery插件formValidator实现表单验证
2016/05/23 Javascript
react实现菜单权限控制的方法
2017/12/11 Javascript
微信小程序实现图片上传功能
2018/05/28 Javascript
JS高级技巧(简洁版)
2018/07/29 Javascript
webpack css加载和图片加载的方法示例
2018/09/11 Javascript
解决Vue-cli npm run build生产环境打包,本地不能打开的问题
2018/09/20 Javascript
layui树形菜单动态遍历的例子
2019/09/23 Javascript
Javascript数组及类数组相关原理详解
2020/10/29 Javascript
如何在vue 中使用柱状图 并自修改配置
2021/01/21 Vue.js
javascript实现拼图游戏
2021/01/29 Javascript
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
pyQt5实时刷新界面的示例
2019/06/25 Python
PageFactory设计模式基于python实现
2020/04/14 Python
解决Keras中CNN输入维度报错问题
2020/06/29 Python
解决TensorFlow调用Keras库函数存在的问题
2020/07/06 Python
分享29个基于Bootstrap的HTML5响应式网页设计模板
2015/11/19 HTML / CSS
Agoda中文官网:安可达(低价预订全球酒店)
2021/01/18 全球购物
什么是事务?事务有哪些性质?
2012/03/11 面试题
描述RIP和OSPF区别以及特点
2015/01/17 面试题
迟到检讨书5000字
2014/01/31 职场文书
群众路线教育实践活动学习笔记
2014/11/05 职场文书
2015年司机工作总结
2015/04/23 职场文书
民事上诉状范文
2015/05/22 职场文书
健康教育主题班会
2015/08/14 职场文书
2015年六年级班主任工作总结
2015/10/15 职场文书
2016党性教育学习心得体会
2016/01/21 职场文书
导游词之无锡华莱坞
2019/12/02 职场文书
Nginx location 和 proxy_pass路径配置问题小结
2021/09/04 Servers