与Pandas

时间:2018-04-11 08:08:39

标签: pandas merge sum sparse-matrix

考虑两个数据框,其中Z列包含整数(尽管我们也可以将其视为仅包含离散集合中的值),

df_1

A | B | Z | PROB
--+---+---+-----
. | . | . |  .
. | . | . |  .
. | . | . |  .

df_2

C | D | Z | PROB
--+---+---+-----
. | . | . |  .
. | . | . |  .
. | . | . |  .

我希望我现在正在合并Z

df = pd.merge(df1, df2, on=['Z'])

获取

df

A | B | C | D | Z | PROB_x | PROB_y
--+---+---+---+---+--------+-------
. | . | . | . | . |    .   |    .
. | . | . | . | . |    .   |    .
. | . | . | . | . |    .   |    .

然后乘以概率列

df['PROB'] = df['PROB_x']*df['PROB_y']

尝试删除旧的概率列(尽管这会导致我的计算机因较大的问题而崩溃)。

df.drop(['PROB_x', 'PROB_y'], axis=1, inplace=True)

最后进行组汇总以获得每个(A, B), (C, D)组合的概率

df.groupby(['A', 'B', 'C', 'D']).sum()

现在,如果我们看看我们的初始问题,我们可以看到它实际上看起来像一个稀疏的矩阵x矩阵'问题。让X成为(A,B)对到整数的映射,Y(C,D)对到整数的映射。

然后,转换后的df_1变为

df_1_mapped

X | Z | PROB
--+---+-----
. | . |  .
. | . |  .
. | . |  .

df_2变为

df_2_mapped

Y | Z | PROB
--+---+-----
. | . |  .
. | . |  .
. | . |  .

现在都是稀疏的COO格式。我们真正想要的是

df_1_mapped * df_2_mapped.T

稀疏矩阵乘法我相信它可以比我正在做的merge-product-sum(可能首先转换稀疏格式)更有效。这给了

X | Y | PROB
--+---+-----
. | . |  .
. | . |  .
. | . |  .

其中.T表示转置​​。

因此,我认为必须有一种比

更有效的方式来做我想做的事情
df = pd.merge(df1, df2, on=['Z'])
df['PROB'] = df['PROB_x']*df['PROB_y']
df.drop(['PROB_x', 'PROB_y'], axis=1, inplace=True)
df.groupby(['A', 'B', 'C', 'D']).sum()

我的问题是,这是在Pandas中实施的更有效的方法吗?我该怎么做?

2 个答案:

答案 0 :(得分:0)

可能会减少使用的最大内存的小建议。没有测试过没有示例数据,但想法只是重用一个列然后删除一个而不是创建一个新的然后丢弃两个。这有用吗?

df = pd.merge(df1, df2, on=['Z'],suffixes=('','_y'))
df['PROB'] = df['PROB']*df['PROB_y']
df.drop(['PROB_y'], axis=1, inplace=True)
df.groupby(['A', 'B', 'C', 'D']).sum()

答案 1 :(得分:0)

这可以通过将Pandas数据帧转换为稀疏Scipy矩阵来解决,并且以这种方式实现它的速度更快,内存更少。请参阅此存储库以获取执行此操作的代码:https://github.com/rwolst/pandas-merge-product-sum

但请注意,我更倾向于使用严格的Pandas解决方案,因此不会接受这个答案,尽管它可能对其他人有用。