棘手的稀疏矩阵操作+表面图

时间:2014-08-13 20:09:10

标签: python numpy scipy

我有两个大的scipy稀疏矩阵,代表时间序列数据。在第一行中,每行表示用户在几个月内(列)收听的音乐,该行中的每个值都是他们收听该月份的歌曲数量。因此数据看起来像这样:

[[ 866.,  242., ...  72.,  793.],
 [ 566.,  419., ... 886.,  985.],
 [ 755.,  474., ... 999.,  453.],
 ...
 [ 237.,  495., ...  40.,  679.]]

第二个矩阵具有相同的形状,并直接映射到第一个矩阵。也就是说,每行对应于同一用户,并且每列对应于与其他矩阵中相同的月份。但是这个矩阵中的每个条目都是一个二进制(1/0),表示该月份是否为该用户发生了特定事件(让他们称之为E)。因此它看起来像这样:

[[ 1,  0, ... 1,  0],
 [ 0,  1, ... 1,  0],
 [ 1,  0, ... 1,  0],
 ...
 [ 1,  1, ... 1,  1]])

鉴于这一切,这就是我的目标。我想生成具有以下尺寸的3D曲面图:

X:时间(因此,对应于矩阵中的列的月份) Y:分档音乐听(即第一个矩阵中的值,分为100个分箱) Z:每个X,Y配对发生第二个矩阵中E的比例。

因此,Z的特定值可能是在第13个月用户收听40-70首歌曲(或任何分组生成的)所有情况下E发生的时间比例(即平均值)。这个想法是查看E发生的可能性,作为用户听多少的同时功能,以及他们何时进行聆听。

我可以想到一些方法可以做到这一点,但这些是大矩阵(800万行X 90列),所以我想要一些非常高效的东西。作为一个中间步骤,我知道我需要为X,Y和Z中的每一个生成数组,并且我确信我可以做一些聪明的矩阵操作来获得它们,但是我&# 39;我不确定如何开始。

1 个答案:

答案 0 :(得分:1)

这是典型的分箱或分组问题;它看起来像下面的代码应该做。您应该从这里复制并保存分组代码: http://pastebin.com/c5WLWPbp

import numpy as np
from itertools import izip
from grouping import group_by

users   = 100
months  = 20
binsize = 40
bins    = 500/binsize+1

counts = np.random.randint(0,500, size=(users, months))
events = np.random.randint(0,2,   size=(users, months))

binned = np.zeros((bins, months), np.float)
for b, c, e in izip(binned.T, counts.T, events.T):
    i, s = group_by(c / binsize).mean(e.astype(np.float))
    b[i] = s
print binned

请注意,代码在几个月内没有矢量化,这并不理想,但如果我们谈论的是90个月和数百万用户,那么几个月的迭代开销应该是微不足道的。在幕后发生的分组非常有效地实现。