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 相关文章推荐
windows上安装Anaconda和python的教程详解
Mar 28 Python
python Pexpect 实现输密码 scp 拷贝的方法
Jan 03 Python
PyQt5实现让QScrollArea支持鼠标拖动的操作方法
Jun 19 Python
新手入门Python编程的8个实用建议
Jul 12 Python
django-初始配置(纯手写)详解
Jul 30 Python
python系列 文件操作的代码
Oct 06 Python
pycharm 激活码及使用方式的详细教程
May 12 Python
Python利用Xpath选择器爬取京东网商品信息
Jun 01 Python
基于Keras的格式化输出Loss实现方式
Jun 17 Python
基于OpenCV的网络实时视频流传输的实现
Nov 15 Python
python爬取股票最新数据并用excel绘制树状图的示例
Mar 01 Python
python 办公自动化——基于pyqt5和openpyxl统计符合要求的名单
May 25 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面向对象全攻略 (十四) php5接口技术
2009/09/30 PHP
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
php+xml编程之SimpleXML的应用实例
2015/01/24 PHP
PHP微信支付开发实例
2016/06/22 PHP
在textarea中显示html页面的javascript代码
2007/04/20 Javascript
JQueryEasyUI datagrid框架的进阶使用
2013/04/08 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
Javascript中的apply()方法浅析
2015/03/15 Javascript
ES6学习之变量的解构赋值
2017/02/12 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
35个最好用的Vue开源库(史上最全)
2019/01/03 Javascript
PostgreSQL Node.js实现函数计算方法示例
2019/02/12 Javascript
Vue实现点击导航栏当前标签后变色功能
2020/08/19 Javascript
使用js和canvas实现时钟效果
2020/09/08 Javascript
Nuxt的动态路由和参数校验操作
2020/11/09 Javascript
Vue 事件的$event参数=事件的值案例
2021/01/29 Vue.js
[50:44]DOTA2-DPC中国联赛 正赛 SAG vs Dragon BO3 第二场 2月22日
2021/03/11 DOTA
Python中生成器和yield语句的用法详解
2015/04/17 Python
python显示生日是星期几的方法
2015/05/27 Python
python直接访问私有属性的简单方法
2016/07/25 Python
Python实现的快速排序算法详解
2017/08/01 Python
Python hashlib模块用法实例分析
2018/06/12 Python
python leetcode 字符串相乘实例详解
2018/09/03 Python
python验证身份证信息实例代码
2019/05/06 Python
解决Django Haystack全文检索为空的问题
2020/05/19 Python
简单了解Python变量作用域正确使用方法
2020/06/12 Python
Virtualenv 搭建 Py项目运行环境的教程详解
2020/06/22 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
使用CSS3来代替JS实现交互
2017/08/10 HTML / CSS
地球上最先进的胡子和头发修剪器:Bevel
2018/01/23 全球购物
国际贸易专业个人职业生涯规划
2014/02/15 职场文书
高中军训感言500字
2014/02/24 职场文书
2015年社区居委会工作总结
2015/05/18 职场文书
通知怎么写?
2019/04/17 职场文书
Python图像处理之图像拼接
2021/04/28 Python
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android