假设我有两张桌子A
和B
.
表A
具有多级索引(a, b)
和一列 (ts)。
b
明确确定 ts。
A = pd.DataFrame(
[('a', 'x', 4),
('a', 'y', 6),
('a', 'z', 5),
('b', 'x', 4),
('b', 'z', 5),
('c', 'y', 6)],
columns=['a', 'b', 'ts']).set_index(['a', 'b'])
AA = A.reset_index()
表B
是另一个具有非唯一索引 ( a
) 的单列 (ts) 表。ts 在每个组的“内部”排序,即B.ix[x]
针对每个 x 排序。此外,总是有一个值B.ix[x]
大于或等于 中的值A
。
B = pd.DataFrame(
dict(a=list('aaaaabbcccccc'),
ts=[1, 2, 4, 5, 7, 7, 8, 1, 2, 4, 5, 8, 9])).set_index('a')
其中的语义是B
包含对索引指示的类型事件发生的观察。
我想从B
每个事件类型的第一次出现的时间戳中A
找到每个b
. 换句话说,我想得到一个具有相同形状的表格A
,而不是 ts 包含由 table 指定的“ts 之后出现的最小值” B
。
所以,我的目标是:
C:
('a', 'x') 4
('a', 'y') 7
('a', 'z') 5
('b', 'x') 7
('b', 'z') 7
('c', 'y') 8
我有一些工作代码,但速度非常慢。
C = AA.apply(lambda row: (
row[0],
row[1],
B.ix[row[0]].irow(np.searchsorted(B.ts[row[0]], row[2]))), axis=1).set_index(['a', 'b'])
剖析显示罪魁祸首很明显B.ix[row[0]].irow(np.searchsorted(B.ts[row[0]], row[2])))
。但是,从长远来看,使用合并/连接的标准解决方案会占用过多的 RAM。
考虑到现在我有 1000 个a
,假设每个 a 的平均 b 数是恒定的(可能是 100-200),并考虑每个 a 的观察数可能是 300 左右。在生产中,我将再有 1000a
个s。
1,000,000 x 200 x 300 = 60,000,000,000
行
保存在 RAM 中可能有点太多了,尤其是考虑到我需要的数据完全可以用 C 来描述,就像我上面讨论的那样。
我将如何提高性能?