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学习教程之Numpy和Pandas的使用
Sep 11 Python
python爬虫基本知识
Mar 05 Python
python pandas.DataFrame选取、修改数据最好用.loc,.iloc,.ix实现
Jun 11 Python
对pandas里的loc并列条件索引的实例讲解
Nov 15 Python
pygame游戏之旅 创建游戏窗口界面
Nov 20 Python
python 字符串常用函数详解
Sep 11 Python
Python如何将函数值赋给变量
Apr 28 Python
基于TensorFlow的CNN实现Mnist手写数字识别
Jun 17 Python
Python 串口通信的实现
Sep 29 Python
如何使用python自带IDLE的几种方法
Oct 10 Python
Python3+Appium安装及Appium模拟微信登录方法详解
Feb 16 Python
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
Apr 14 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录入页面中动态从数据库中提取数据的实现
2006/10/09 PHP
PHP通用检测函数集合
2011/02/08 PHP
PHP实现二维数组按某列进行排序的方法
2016/11/18 PHP
PHP 实现字符串翻转(包含中文汉字)的实现代码
2017/04/01 PHP
Javascript 两个窗体之间传值实现代码
2009/09/25 Javascript
node.js中的events.emitter.once方法使用说明
2014/12/10 Javascript
高效Web开发的10个jQuery代码片段
2016/07/22 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
JS之相等操作符详解
2016/09/13 Javascript
Servlet实现文件上传,可多文件上传示例
2016/12/05 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
微信小程序之电影影评小程序制作代码
2017/08/03 Javascript
vue-cli项目中使用Mockjs详解
2018/05/14 Javascript
Vue+element-ui 实现表格的分页功能示例
2018/08/18 Javascript
jQuery实现高级检索功能
2019/05/28 jQuery
vue输入框使用模糊搜索功能的实现代码
2020/05/26 Javascript
[00:59]DOTA2英雄背景故事——上古巨神
2020/06/28 DOTA
Python time模块详解(常用函数实例讲解,非常好)
2014/04/24 Python
python静态方法实例
2015/01/14 Python
Python实现翻转数组功能示例
2018/01/12 Python
python中ASCII码和字符的转换方法
2018/07/09 Python
python学生信息管理系统(初级版)
2018/10/17 Python
flask-restful使用总结
2018/12/04 Python
Python实现的简单线性回归算法实例分析
2018/12/26 Python
python实现远程控制电脑
2019/05/23 Python
python基础 range的用法解析
2019/08/23 Python
django drf框架自带的路由及最简化的视图
2019/09/10 Python
使用Matplotlib 绘制精美的数学图形例子
2019/12/13 Python
CSS3的 fit-content实现水平居中
2017/09/07 HTML / CSS
iHerb台湾:维生素、保健品和健康产品
2018/01/31 全球购物
工程造价专业大学生自荐信
2013/10/01 职场文书
消防先进事迹材料
2014/02/10 职场文书
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
村级四风对照检查材料
2014/08/24 职场文书
2014年仓库工作总结
2014/11/20 职场文书
安装工程师岗位职责
2015/02/13 职场文书