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验证企业工商注册码
Oct 25 Python
Python Queue模块详细介绍及实例
Dec 27 Python
python监控键盘输入实例代码
Feb 09 Python
python+numpy+matplotalib实现梯度下降法
Aug 31 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
Jun 26 Python
Python读取xlsx文件的实现方法
Jul 04 Python
Python的垃圾回收机制详解
Aug 28 Python
Python 中 -m 的典型用法、原理解析与发展演变
Nov 11 Python
PyQt5事件处理之定时在控件上显示信息的代码
Mar 25 Python
python使用Thread的setDaemon启动后台线程教程
Apr 25 Python
python 远程执行命令的详细代码
Feb 15 Python
python使用shell脚本创建kafka连接器
Apr 29 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&mysql(三)
2006/10/09 PHP
php通过获取头信息判断图片类型的方法
2015/06/26 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
2016/01/22 PHP
session 加入redis的实现代码
2016/07/15 PHP
Laravel框架基于ajax实现二级联动功能示例
2019/01/17 PHP
javascript动画之圆形运动,环绕鼠标运动作小球
2010/07/20 Javascript
浅谈Javascript嵌套函数及闭包
2010/11/09 Javascript
javascript中HTMLDOM操作详解
2014/12/11 Javascript
浅谈Javascript 数组与字典
2015/01/29 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
javascript实现点击商品列表checkbox实时统计金额的方法
2015/05/15 Javascript
老生常谈js动态添加事件--- 事件委托
2016/07/19 Javascript
利用canvas实现的加载动画效果实例代码
2017/07/05 Javascript
如何使用vuex实现兄弟组件通信
2018/11/02 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
2019/03/04 Javascript
vue iview多张图片大图预览、缩放翻转
2019/07/13 Javascript
vue解决花括号数据绑定不成功的问题
2019/10/30 Javascript
Jquery $.map使用方法实例详解
2020/09/01 jQuery
详解JavaScript 高阶函数
2020/09/14 Javascript
[03:45]Newbee战队出征西雅图 决战2016国际邀请赛
2016/08/02 DOTA
python教程之用py2exe将PY文件转成EXE文件
2014/06/12 Python
python合并同类型excel表格的方法
2018/04/01 Python
python查看模块安装位置的方法
2018/10/16 Python
pandas 数据归一化以及行删除例程的方法
2018/11/10 Python
Python正则表达式和元字符详解
2018/11/29 Python
Python面向对象实现一个对象调用另一个对象操作示例
2019/04/08 Python
Pytorch中accuracy和loss的计算知识点总结
2019/09/10 Python
python GUI库图形界面开发之PyQt5信号与槽基本操作
2020/02/25 Python
浅谈keras中的batch_dot,dot方法和TensorFlow的matmul
2020/06/18 Python
Maje德国官网:法国女性成衣品牌
2017/02/10 全球购物
德国圣伯纳德草药屋:Kräuterhaus Sanct Bernhard(有中文站)
2018/08/05 全球购物
技术总监个人的自我评价范文
2013/12/18 职场文书
师德演讲稿范文
2014/05/06 职场文书
留守儿童工作方案
2014/06/02 职场文书
会计个人实习计划书
2014/08/15 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书