【问题标题】:Using numpy.unique on multiple columns of a pandas.DataFrame在 pandas.DataFrame 的多列上使用 numpy.unique
【发布时间】:2017-08-27 07:16:54
【问题描述】:

我希望使用numpy.unique 来获取pandas.DataFrame 的两列的反向唯一索引。

我知道如何在一栏上使用它:

u, rev = numpy.unique(df[col], return_inverse=True)

但我想在多个列上使用它。例如,如果 df 看起来像:

    0   1   
0   1   1
1   1   2
2   2   1
3   2   1
4   3   1

然后我想得到反向索引:

[0,1,2,2,3]

【问题讨论】:

    标签: python-3.x pandas numpy dataframe uniqueidentifier


    【解决方案1】:

    方法#1

    这是一种 NumPy 方法,将每一行转换为标量,每行都将每一行视为二维(用于 2 列数据)网格上的一个索引元组 -

    def unique_return_inverse_2D(a): # a is array
        a1D = a.dot(np.append((a.max(0)+1)[:0:-1].cumprod()[::-1],1))
        return np.unique(a1D, return_inverse=1)[1]
    

    如果数据中有负数,我们也需要使用min 来获取这些标量。因此,在这种情况下,请使用 a.max(0) - a.min(0) + 1 代替 a.max(0) + 1

    方法 #2

    这是另一个 NumPy 的基于视图的解决方案,重点关注性能,灵感来自 this smart solution by @Eric -

    def unique_return_inverse_2D_viewbased(a): # a is array
        a = np.ascontiguousarray(a)
        void_dt = np.dtype((np.void, a.dtype.itemsize * np.prod(a.shape[1:])))
        return np.unique(a.view(void_dt).ravel(), return_inverse=1)[1]
    

    示例运行 -

    In [209]: df
    Out[209]: 
        0   1   2   3
    0  21   7  31  69
    1  62  75  22  62  # ----|
    2  16  46   9  31  #     |==> Identical rows, so must have same IDs
    3  62  75  22  62  # ----|
    4  24  12  88  15
    
    In [210]: unique_return_inverse_2D(df.values)
    Out[210]: array([1, 3, 0, 3, 2])
    
    In [211]: unique_return_inverse_2D_viewbased(df.values)
    Out[211]: array([1, 3, 0, 3, 2])
    

    【讨论】:

      【解决方案2】:

      我认为您可以将列转换为strings,然后再转换为sum

      u, rev = np.unique(df.astype(str).values.sum(axis=1), return_inverse=True)
      print (rev)
      [0 1 2 2 3]
      

      正如DSM 指出的那样(谢谢),这很危险。

      另一种解决方案是将行转换为tuples

      u, rev = np.unique(df.apply(tuple, axis=1), return_inverse=True)
      print (rev)
      [0 1 2 2 3]
      

      【讨论】:

      • 危险。这将无法区分第 11,2 行和第 1,12 行。
      猜你喜欢
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      • 2019-01-25
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      相关资源
      最近更新 更多