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 CGI脚本的教程
Jun 29 Python
Python面向对象类的继承实例详解
Jun 27 Python
Pandas 按索引合并数据集的方法
Nov 15 Python
selenium设置proxy、headers的方法(phantomjs、Chrome、Firefox)
Nov 29 Python
python保存字典和读取字典的实例代码
Jul 07 Python
在python中画正态分布图像的实例
Jul 08 Python
Pandas实现DataFrame按行求百分数(比例数)
Dec 27 Python
python实现滑雪游戏
Feb 22 Python
Python通过socketserver处理多个链接
Mar 18 Python
PyQT5 实现快捷键复制表格数据的方法示例
Jun 19 Python
Python读取Excel一列并计算所有对象出现次数的方法
Sep 04 Python
Pytorch 如何实现LSTM时间序列预测
May 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
新手菜鸟必读:session与cookie的区别
2013/08/22 PHP
PHP字符串的连接的简单实例
2013/12/30 PHP
php使用正则过滤js脚本代码实例
2014/05/10 PHP
PHP中字符安全过滤函数使用小结
2015/02/25 PHP
Avengerls vs Newbee BO3 第三场2.18
2021/03/10 DOTA
基于jquery实现的服务器验证控件的启用和禁用代码
2010/04/27 Javascript
JavaScript中两个感叹号的作用说明
2011/12/28 Javascript
关于jQuery object and DOM element
2013/04/15 Javascript
cookie 最近浏览记录(中文escape转码)具体实现
2013/06/08 Javascript
JS 去除Array中的null值示例代码
2013/11/20 Javascript
jQuery中offsetParent()方法用法实例
2015/01/19 Javascript
jQuery实现图片加载完成后改变图片大小的方法
2016/03/29 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
BootstrapTable加载按钮功能实例代码详解
2017/09/22 Javascript
vue下拉列表功能实例代码
2018/04/08 Javascript
Vue封装的可编辑表格插件方法
2018/08/28 Javascript
微信小程序实现左侧滑栏过程解析
2019/08/26 Javascript
如何基于js判断浏览器版本
2020/02/20 Javascript
[02:36]DOTA2混沌骑士 英雄基础教程
2013/11/26 DOTA
Python实现XML文件解析的示例代码
2018/02/05 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
2019/05/10 Python
PyTorch搭建一维线性回归模型(二)
2019/05/22 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
2019/07/03 Python
python numpy生成等差数列、等比数列的实例
2020/02/25 Python
Django实现列表页商品数据返回教程
2020/04/03 Python
利用 Canvas实现绘画一个未闭合的带进度条的圆环
2019/07/26 HTML / CSS
经典大学生求职信范文
2014/01/06 职场文书
董事长助理岗位职责
2014/02/18 职场文书
2014年教师节寄语
2014/04/03 职场文书
物流业务员岗位职责
2015/04/03 职场文书
农村环境卫生倡议书
2015/04/29 职场文书
会计试用期工作总结2015
2015/05/28 职场文书
个人售房合同协议书
2016/03/21 职场文书
python 如何在 Matplotlib 中绘制垂直线
2021/04/02 Python
详解GaussDB for MySQL性能优化
2021/05/18 MySQL