基于熊猫中的对称矩阵从系列中删除重复项

约翰切斯

我是Pandas的新手,无法找到针对以下问题的简洁解决方案。

假设我有一系列基于对称(距离)矩阵的数据,从以下系列中删除重复项的最有效方法是什么?

from pandas import DataFrame
df = DataFrame([[0, 1, 2],
                [1, 0, 3],
                [2, 3, 0]], 
               index=['a', 'b', 'c'], 
               columns=['a', 'b', 'c'])
ser = df.stack()
ser

a  a    0
   b    1
   c    2
b  a    1
   b    0
   c    3
c  a    2
   b    3
   c    0

我想做的是删除重复的对,因为矩阵是对称的。输出应如下所示

a  a     0
   b     1
   c     2
b  b     0
   c     3
c  c     0
空中飞人

以下代码的运行速度比当前接受的答案快:

import numpy as np

def dm_to_series1(df):
    df = df.astype(float)
    df.values[np.triu_indices_from(df, k=1)] = np.nan
    return df.unstack().dropna()

将的类型DataFrame转换为,float以便可以使用使元素为空np.nan实际上,距离矩阵可能已经存储了浮点数,因此此步骤可能并非严格必要。上部三角形(不包括对角线)是零化和转换之后被去除这些条目DataFrame到一个Series

我对当前接受的解决方案进行了调整,以比较运行时间。请注意,我将其更新为使用集合而不是列表,以加快运行速度:

def dm_to_series2(df):
    ser = df.stack()

    seen = set()
    for tup in ser.index.tolist():
        if tup[::-1] in seen:
            continue
        seen.add(tup)

    return ser[seen]

在原始示例数据集上测试这两个解决方案:

import pandas as pd

df = pd.DataFrame([[0, 1, 2],
                   [1, 0, 3],
                   [2, 3, 0]], 
                  index=['a', 'b', 'c'], 
                  columns=['a', 'b', 'c'])

我的解决方案:

In [4]: %timeit dm_to_series1(df)
1000 loops, best of 3: 538 µs per loop

@Marius的解决方案:

In [5]: %timeit dm_to_series2(df)
1000 loops, best of 3: 816 µs per loop

我还通过使用scikit-bioskbio.stats.distance.randdm函数随机生成50x50矩阵并将其转换为,对更大的距离矩阵进行了测试DataFrame

from skbio.stats.distance import randdm
big_dm = randdm(50)
big_df = pd.DataFrame(big_dm.data, index=big_dm.ids, columns=big_dm.ids)

我的解决方案:

In [7]: %timeit dm_to_series1(big_df)
1000 loops, best of 3: 649 µs per loop

@Marius的解决方案:

In [8]: %timeit dm_to_series2(big_df)
100 loops, best of 3: 3.61 ms per loop

请注意,我的解决方案可能不如@Marius的解决方案节省内存,因为我正在创建输入的副本DataFrame并对其进行修改。如果可以接受修改输入的信息DataFrame,则可以通过使用就地DataFrame操作将代码更新为更高的内存效率

注意:我的解决方案受此SO问题中答案的启发

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章