开发者社区> 问答> 正文

根据行中阈值获取前'n'列的名称

假设我有以下数据:

In [1]: df
Out[1]:
        Student_Name    Maths    Physics    Chemistry    Biology    English
0       John Doe        90       87         81           65         70
1       Jane Doe        82       84         75           73         77
2       Mary Lim        40       65         55           60         70
3       Lisa Ray        55       52         77           62         90

我想在此数据框中添加一列,该列告诉我学生的门槛最高的“ n”门科目,其中科目名称在列名称中可用。假设n = 3threshold = 80。输出如下所示:

In [3]: df
Out[3]:
        Student_Name    Maths    Physics    Chemistry    Biology    English  Top_3_above_80
0       John Doe        90       87         81           65         70       Maths, Physics, Chemistry
1       Jane Doe        82       84         75           73         77       Physics, Maths
2       Mary Lim        40       65         55           60         70       nan
3       Lisa Ray        55       52         77           62         90       English

我尝试使用@jezrael编写的解决方案来解决此问题,其中他们使用numpy.argsort获取“ n”列的排序值的位置,但是我无法设置阈值,在该阈值以下不应考虑任何问题。

问题来源:stackoverflow

展开
收起
is大龙 2020-03-25 09:25:01 3505 0
1 条回答
写回答
取消 提交回答
  • 想法是首先通过丢失DataFrame.where中的值来替换不匹配的值,然后使用numpy.argsort应用解决方案。根据numpy.where中的count个不丢失的值按True的数量进行过滤,以将不匹配的值替换为空字符串。

    最后是将值加入列表推导中,并过滤掉缺少值的不匹配行:

    df1 = df.iloc[:, 1:]
    
    m = df1 > 80
    count = m.sum(axis=1)
    arr = df1.columns.values[np.argsort(-df1.where(m), axis=1)]
    
    m = np.arange(arr.shape[1]) < count[:, None]
    a = np.where(m, arr, '')
    
    L = [', '.join(x).strip(', ') for x in a]
    df['Top_3_above_80'] = pd.Series(L, index=df.index)[count > 0]
    print (df)
      Student_Name  Maths  Physics  Chemistry  Biology  English  \
    0     John Doe     90       87         81       65       70   
    1     Jane Doe     82       84         75       73       77   
    2     Mary Lim     40       65         55       60       70   
    3     Lisa Ray     55       52         77       62       90   
    
                  Top_3_above_80  
    0  Maths, Physics, Chemistry  
    1             Physics, Maths  
    2                        NaN  
    3                    English  
    

    如果性能不重要,则每行使用Series.nlargest,但是如果使用大的DataFrame的话,它的确很慢:

    df1 = df.iloc[:, 1:]
    m = df1 > 80
    count = m.sum(axis=1)
    
    df['Top_3_above_80'] = (df1.where(m)
                               .apply(lambda x: ', '.join(x.nlargest(3).index), axis=1)[count > 0])
    print (df)
      Student_Name  Maths  Physics  Chemistry  Biology  English  \
    0     John Doe     90       87         81       65       70   
    1     Jane Doe     82       84         75       73       77   
    2     Mary Lim     40       65         55       60       70   
    3     Lisa Ray     55       52         77       62       90   
    
                  Top_3_above_80  
    0  Maths, Physics, Chemistry  
    1             Physics, Maths  
    2                        NaN  
    3                    English  
    

    性能

    #4k rows
    df = pd.concat([df] * 1000, ignore_index=True)
    #print (df)
    
    def f1(df):
        df1 = df.iloc[:, 1:]
        m = df1 > 80
        count = m.sum(axis=1)
        arr = df1.columns.values[np.argsort(-df1.where(m), axis=1)]
    
        m = np.arange(arr.shape[1]) < count[:, None]
        a = np.where(m, arr, '')
    
        L = [', '.join(x).strip(', ') for x in a]
        df['Top_3_above_80'] = pd.Series(L, index=df.index)[count > 0]
        return df
    
    def f2(df):
        df1 = df.iloc[:, 1:]
        m = df1 > 80
        count = m.sum(axis=1)
    
        df['Top_3_above_80'] = (df1.where(m).apply(lambda x: ', '.join(x.nlargest(3).index), axis=1)[count > 0])
        return df
    
    In [210]: %timeit (f1(df.copy()))
    19.3 ms ± 272 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [211]: %timeit (f2(df.copy()))
    2.43 s ± 61.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    回答来源:stackoverflow

    2020-03-25 09:25:09
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载