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开发的单词频率统计工具wordsworth使用方法
Jun 25 Python
python基础教程之缩进介绍
Aug 29 Python
python的Template使用指南
Sep 11 Python
Python os模块学习笔记
Jun 21 Python
Python进阶_关于命名空间与作用域(详解)
May 29 Python
windows下python之mysqldb模块安装方法
Sep 07 Python
深入浅析Python中的yield关键字
Jan 24 Python
使用PyCharm创建Django项目及基本配置详解
Oct 24 Python
python实现月食效果实例代码
Jun 18 Python
python 进程的几种创建方式详解
Aug 29 Python
Python3 利用face_recognition实现人脸识别的方法
Mar 13 Python
Restful_framework视图组件代码实例解析
Nov 17 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 获取MSN好友列表的代码(2009-05-14测试通过)
2009/09/09 PHP
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
2010/11/01 PHP
php生成excel列序号代码实例
2013/12/24 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
删除PHP数组中头部、尾部、任意元素的实现代码
2017/04/10 PHP
一个刚完成的layout(拖动流畅,不受iframe影响)
2007/08/17 Javascript
javascript 在firebug调试时用console.log的方法
2012/05/10 Javascript
原生javascript实现获取指定元素下所有后代元素的方法
2014/10/28 Javascript
使用javascript实现简单的选项卡切换
2015/01/09 Javascript
个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
2015/06/10 Javascript
Jquery基础教程之DOM操作
2015/08/19 Javascript
AngularJS教程之简单应用程序示例
2016/08/16 Javascript
使用vue实现多规格选择实例(SKU)
2019/08/23 Javascript
js消除图片小游戏代码
2019/12/11 Javascript
使用JavaScript实现贪吃蛇游戏
2020/09/29 Javascript
Python对list列表结构中的值进行去重的方法总结
2016/05/07 Python
Python实现基于TCP UDP协议的IPv4 IPv6模式客户端和服务端功能示例
2018/03/22 Python
django表单实现下拉框的示例讲解
2018/05/29 Python
python scipy卷积运算的实现方法
2019/09/16 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
关于python3.7安装matplotlib始终无法成功的问题的解决
2020/07/28 Python
MoviePy常用剪辑类及Python视频剪辑自动化
2020/12/18 Python
详解CSS3选择器:nth-child和:nth-of-type之间的差异
2017/09/18 HTML / CSS
俄罗斯药房连锁店:ASNA
2020/06/20 全球购物
大学生职业生涯规划书范文
2014/01/14 职场文书
职业生涯规划书前言
2014/04/15 职场文书
班组建设经验交流材料
2014/05/12 职场文书
公务员个人考察材料
2014/12/23 职场文书
研究生就业推荐表导师评语
2014/12/31 职场文书
大学推普周活动总结
2015/05/07 职场文书
勇敢的心观后感
2015/06/09 职场文书
优秀毕业生主要事迹材料
2015/11/04 职场文书
技术入股合作协议书
2016/03/21 职场文书
终止合同协议书范本
2016/03/22 职场文书
nginx访问报403错误的几种情况详解
2022/07/23 Servers
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS