我有两个大的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;我不确定如何开始。
答案 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个月和数百万用户,那么几个月的迭代开销应该是微不足道的。在幕后发生的分组非常有效地实现。