【问题标题】:Fastest way to sort each row in a pandas dataframe对熊猫数据框中的每一行进行排序的最快方法
【发布时间】:2014-11-07 04:50:51
【问题描述】:

我需要找到最快的方法来对包含数百万行和大约一百列的数据框中的每一行进行排序。

所以是这样的:

A   B   C   D
3   4   8   1
9   2   7   2

需要成为:

A   B   C   D
8   4   3   1
9   7   2   2

现在我正在对每一行应用排序并逐行构建一个新的数据框。我还在为每一行做一些额外的、不太重要的事情(因此我使用 pandas 而不是 numpy)。改为创建列表列表然后立即构建新数据框会更快吗?还是我需要去 cython?

【问题讨论】:

  • 转置、排序、转回?
  • 转置它如何使排序更快?
  • 您只需更改映射的“视图”...所以您仍然需要进行排序,但是您将 1mx100 变成 100x1m 在同一个空间中,排序,然后反转它,您只是对数据有不同的看法
  • 我还是一头雾水。我只需要对一百万列而不是一百万行进行排序。

标签: python performance pandas


【解决方案1】:

可以尝试这种方法来保持 df 的完整性:

import pandas as pd 
import numpy as np

A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five']) 
print (A) 
print(type(A))
   one  two  three  four  five
0   85   27     64    50    55
1    3   90     65    22     8
2    0    7     64    66    82
3   58   21     42    27    30
<class 'pandas.core.frame.DataFrame'>
B = A.apply(lambda x: np.sort(x), axis=1, raw=True) 
print(B) 
print(type(B))
   one  two  three  four  five
0   27   50     55    64    85
1    3    8     22    65    90
2    0    7     64    66    82
3   21   27     30    42    58
<class 'pandas.core.frame.DataFrame'>

【讨论】:

    【解决方案2】:

    不使用pd.DataFrame 构造函数,一个更简单的方法是使用双括号来分配排序后的值:

    原始数据框

    A   B   C   D
    3   4   8   1
    9   2   7   2
    
    df[['A', 'B', 'C', 'D']] = np.sort(df)[:, ::-1]
    
       A  B  C  D
    0  8  4  3  1
    1  9  7  2  2
    

    这样你也可以对部分列进行排序:

    df[['B', 'C']] = np.sort(df[['B', 'C']])[:, ::-1]
    
       A  B  C  D
    0  3  8  4  1
    1  9  7  2  2
    

    【讨论】:

      【解决方案3】:

      我想我会在 numpy 中这样做:

      In [11]: a = df.values
      
      In [12]: a.sort(axis=1)  # no ascending argument
      
      In [13]: a = a[:, ::-1]  # so reverse
      
      In [14]: a
      Out[14]:
      array([[8, 4, 3, 1],
             [9, 7, 2, 2]])
      
      In [15]: pd.DataFrame(a, df.index, df.columns)
      Out[15]:
         A  B  C  D
      0  8  4  3  1
      1  9  7  2  2
      

      我原以为这可能有效,但它对列进行了排序:

      In [21]: df.sort(axis=1, ascending=False)
      Out[21]:
         D  C  B  A
      0  1  8  4  3
      1  2  7  2  9
      

      啊,熊猫举起:

      In [22]: df.sort(df.columns, axis=1, ascending=False)
      

      ValueError:按列排序时,轴必须为0(行)

      【讨论】:

      • df.sort 已弃用。你会如何在最新版本的 pandas 中做到这一点?
      • 救命稻草。谢谢。
      【解决方案4】:

      你可以使用 pd.apply。

      Eg:
      
      A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five']) 
      print (A)
      
         one  two  three  four  five
      0    2   75     44    53    46
      1   18   51     73    80    66
      2   35   91     86    44    25
      3   60   97     57    33    79
      
      A = A.apply(np.sort, axis = 1) 
      print(A)
      
         one  two  three  four  five
      0    2   44     46    53    75
      1   18   51     66    73    80
      2   25   35     44    86    91
      3   33   57     60    79    97
      

      由于您希望它按降序排列,您可以简单地将数据框乘以 -1 并对其进行排序。

      A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five'])
      A = A * -1
      A = A.apply(np.sort, axis = 1)
      A = A * -1
      

      【讨论】:

        【解决方案5】:

        要添加到@Andy-Hayden 给出的答案,在整个框架中就地执行此操作...不太确定为什么会这样,但确实如此。订单似乎无法控制。

            In [97]: A = pd.DataFrame(np.random.randint(0,100,(4,5)), columns=['one','two','three','four','five'])
        
            In [98]: A
            Out[98]: 
            one  two  three  four  five
            0   22   63     72    46    49
            1   43   30     69    33    25
            2   93   24     21    56    39
            3    3   57     52    11    74
        
            In [99]: A.values.sort
            Out[99]: <function ndarray.sort>
        
            In [100]: A
            Out[100]: 
            one  two  three  four  five
            0   22   63     72    46    49
            1   43   30     69    33    25
            2   93   24     21    56    39
            3    3   57     52    11    74
        
            In [101]: A.values.sort()
        
            In [102]: A
            Out[102]: 
            one  two  three  four  five
            0   22   46     49    63    72
            1   25   30     33    43    69
            2   21   24     39    56    93
            3    3   11     52    57    74
            In [103]: A = A.iloc[:,::-1]
        
            In [104]: A
            Out[104]: 
            five  four  three  two  one
            0    72    63     49   46   22
            1    69    43     33   30   25
            2    93    56     39   24   21
            3    74    57     52   11    3
        

        我希望有人能解释为什么会这样,很高兴它有效 8)

        【讨论】:

        • A.values 返回 A 的 numpy 表示,所以这个 sort 只是一个 numpy 排序,就地完成。
        猜你喜欢
        • 2019-04-12
        • 2019-03-15
        • 2021-10-08
        • 2015-11-06
        • 2016-10-13
        相关资源
        最近更新 更多