【问题标题】:Sorting rows by the number of list elements the row contains按行包含的列表元素的数量对行进行排序
【发布时间】:2022-01-19 18:15:56
【问题描述】:

以下表为例:

index column_1 column_2
0 bli bli d e
1 bla bla a b c d e
2 ble ble a b c

如果我给出token_list = ['c', 'e'],我想按照每行在第 2 列中包含的标记的次数对表格进行排序。

通过订购表格,我应该得到以下信息:

index column_1 column_2 score_tmp
1 bla bla a b c d e 2
0 bli bli d e 1
2 ble ble a b c 1

目前,我已经达到了以下方法,但这需要很多时间。我怎样才能改善时间?提前谢谢你。

df['score_tmp'] = df[['column_2']].apply(
            lambda x: len([True for token in token_list if
            token in str(x['column_2'])]), axis=1)
results = df.sort_values('score_tmp', ascending=False).loc[df['score_tmp'] == len(token_list)].reset_index(inplace=False).to_dict('records')

【问题讨论】:

    标签: python pandas optimization timeit


    【解决方案1】:

    您可以split column_2 基于空格,将每一行转换为set,然后将df.applyset intersectionsort_values 一起使用:

    In [200]: df['matches'] = df.column_2.str.split().apply(lambda x: set(x) & set(token_list)).str.len()
    
    In [204]: df.sort_values('matches', ascending=False).drop('matches', 1)
    Out[204]: 
       index column_1   column_2
    1      1  bla bla  a b c d e
    0      0  bli bli        d e
    2      2  ble ble      a b c
    

    时间安排

    In [208]: def f1():
         ...:     df['score_tmp'] = df[['column_2']].apply(lambda x: len([True for token in token_list if token in str(x['column_2'])]), axis=1)
         ...:     results = df.sort_values('score_tmp', ascending=False).loc[df['score_tmp'] == len(token_list)].reset_index(inplace=False).to_dict('records')
         ...: 
    
    In [209]: def f2():
         ...:     df['matches'] = df.column_2.str.split().apply(lambda x: set(x) & set(token_list)).str.len()
         ...:     df.sort_values('matches', ascending=False).drop('matches', 1)
         ...: 
    
    In [210]: %timeit f1() # solution provided in question
    2.36 ms ± 55.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [211]: %timeit f2() # my solution
    1.22 ms ± 14.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    【讨论】:

      【解决方案2】:

      这是使用str.count()的另一种方式

      df.sort_values('column_2',
                     key = lambda x: x.str.count('|'.join(token_list)),
                     ascending=False)
      

      使用sort_values()key 参数,我们不必制作临时列来进行排序。

      输出:

         index column_1   column_2
      1      1  bla bla  a b c d e
      0      0  bli bli        d e
      2      2  ble ble      a b c
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-17
        • 2010-10-29
        • 1970-01-01
        • 1970-01-01
        • 2022-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多