【问题标题】:Efficient merge-product-sum with Pandas与 Pandas 的高效合并积和
【发布时间】:2018-09-21 00:37:35
【问题描述】:

考虑两个数据帧,其中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

我相信可以比我正在做的合并乘积和(可能首先转换稀疏格式)更有效地完成稀疏矩阵乘法。这给了

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 中实现了吗?我该怎么做?

【问题讨论】:

    标签: pandas merge sum sparse-matrix


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      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()
      

      【讨论】:

        猜你喜欢
        • 2020-03-08
        • 2017-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        相关资源
        最近更新 更多