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使用urllib模块和pyquery实现阿里巴巴排名查询
Jan 16 Python
python处理中文编码和判断编码示例
Feb 26 Python
python 调用win32pai 操作cmd的方法
May 28 Python
Python数据分析之双色球中蓝红球分析统计示例
Feb 03 Python
详解Python if-elif-else知识点
Jun 11 Python
python tkinter组件使用详解
Sep 16 Python
python读取tif图片时保留其16bit的编码格式实例
Jan 13 Python
python数据库操作mysql:pymysql、sqlalchemy常见用法详解
Mar 30 Python
python连接mongodb数据库操作数据示例
Nov 30 Python
python爬虫利用代理池更换IP的方法步骤
Feb 21 Python
python中if嵌套命令实例讲解
Feb 25 Python
Python 使用dict实现switch的操作
Apr 07 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编写的简单页面跳转功能实现代码
2013/11/27 PHP
php中smarty变量修饰用法实例分析
2015/06/11 PHP
PHP7.0版本备注
2015/07/23 PHP
PHP合并discuz用户脚本的方法
2015/08/04 PHP
PHP获取真实IP及IP模拟方法解析
2020/11/24 PHP
onpropertypchange
2006/07/01 Javascript
jQuery初学:find()方法及children方法的区别分析
2011/01/31 Javascript
fancybox modal的完美解决(右上的X)
2012/10/30 Javascript
JQuery 实现在同一页面锚点链接之间的平滑滚动
2014/10/29 Javascript
jQuery实现监控页面所有ajax请求的方法
2015/12/10 Javascript
JavaScript“尽快失败”的原则实例详解
2016/10/08 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
layer实现关闭弹出层刷新父界面功能详解
2017/11/15 Javascript
vuex 解决报错this.$store.commit is not a function的方法
2018/12/17 Javascript
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
原生JS实现微信通讯录
2020/06/18 Javascript
toString.call()通用的判断数据类型方法示例
2020/08/28 Javascript
vue实现div可拖动位置也可改变盒子大小的原理
2020/09/16 Javascript
py中的目录与文件判别代码
2008/07/16 Python
Django代码性能优化与Pycharm Profile使用详解
2018/08/26 Python
在Python中获取两数相除的商和余数方法
2018/11/10 Python
python自动化之Ansible的安装教程
2019/06/13 Python
Python爬虫入门教程01之爬取豆瓣Top电影
2021/01/24 Python
python工具快速为音视频自动生成字幕(使用说明)
2021/01/27 Python
TripAdvisor台湾:全球最大旅游网站
2018/08/26 全球购物
早晨薰衣草在线女性精品店:Morning Lavender
2021/01/04 全球购物
教师岗位职责
2013/11/17 职场文书
大学生职业规划前言模板
2013/12/27 职场文书
大学生找工作求职信
2014/07/09 职场文书
2014年妇联工作总结
2014/11/21 职场文书
单位未婚证明范本
2014/11/25 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
Python自然语言处理之切分算法详解
2021/04/25 Python
Vue实现跑马灯样式文字横向滚动
2021/11/23 Vue.js
Python集合set()使用的方法详解
2022/03/18 Python
漫画「处刑少女的生存之道」第3卷封面公开
2022/03/21 日漫