首页 > 解决方案 > 从行中删除任何 0 值,对行中的值进行降序排列,对于行中的每个非 0 值,将索引、列名和分数返回到新的 df

问题描述

我正在寻找一种更有效的方法来执行以下操作(也许使用布尔掩码和 vecotrization)。我是这个论坛的新手,如果我的第一个问题与预期的不太一样,我深表歉意。

#order each row by values descending
#remove any 0 value column from row
#for each non 0 value return the index, column name, and score to a new dataframe

test_data={'a':[1,0,8,5],
          'b':[36,2,0,6],
          'c':[2,8,100,0],
          'd':[7,8,9,50]}

df=pd.DataFrame(test_data,columns=['a','b','c','d'])

column_names = ['index_row','header','score']

#create empty df with final output columns
df_result = pd.DataFrame(columns = column_names)

row_index=list(df.index.values)
    
for row in row_index:
    
    working_row=row


    #change all 0 values to null and drop any extraneous columns
    subset_cols=df.loc[[working_row],:].replace(0,pd.np.nan).dropna(axis=1,how='any').columns.to_list()

    #order by score
    sub_df = df.loc[[working_row],subset_cols].sort_values(by =row, axis=1, ascending=False)
    
    s_cols = sub_df.columns.to_list()

    scores = sub_df.values.tolist()
    scores = scores[0]
    
    index_row=[]
    header=[]
    score=[]
    
    for count, value in enumerate(scores):
 
        header.append(s_cols[count])
        score.append(value)
        index_row.append(row)
        
        data={'index_row': index_row,
             'header': header,
             'score': score}
        result_frame = pd.DataFrame (data, columns =['index_row','header','score'])
    
    df_result=pd.concat([df_result, result_frame], ignore_index=True)
    
df_result

标签: pythonpandasnumpy

解决方案


您可以直接使用melt并进行一些额外的处理:

df_result = df.reset_index().rename(columns={'index': 'index_row'}).melt(
    id_vars='index_row', var_name='header', value_name='score').query(
        "score!=0").sort_values(['index_row', 'score'], ascending=[True, False]
                                ).reset_index(drop=True)

它按预期给出:

    index_row header  score
0           0      b     36
1           0      d      7
2           0      c      2
3           0      a      1
4           1      c      8
5           1      d      8
6           1      b      2
7           2      c    100
8           2      d      9
9           2      a      8
10          3      d     50
11          3      b      6
12          3      a      5

推荐阅读