Найти имена первых столбцов с наивысшим значением (ненулевых) в каждой строке кадра данных pandas

Предположим, у меня есть кадр данных, например

id     p1 p2 p3 p4  
1      0  9  0  4
2      0  0  0  4
3      1  3 10  7
4      1  5  3  1
5      2  3  7 10

Хотите найти имена столбцов первых n столбцов с наибольшим значением в каждой строке фрейма данных pandas и хотите исключить нулевое значение из первых 3.

id top1 top2 top3
1  p2   p4   
2  p4      
3  p3   p4   p2
4  p2   p3   p4/p1
5  p4   p3   p2

Настоящие решения возвращают имена столбцов, которые также имеют нуль. Есть ли способ исключить нулевые значения. есть это решение

arank = df.apply(np.argsort, axis = 1)
ranked_cols = df.columns.to_series()[arank.values[:,::-1][:,:3]]
new_df = pd.DataFrame(ranked_cols, index=df.index)

есть и другие решения, такие как Найдите имена первых n столбцов с наибольшим значением в каждой строке кадра данных pandas. Можно ли их изменить, чтобы исключить столбцы с нулевым значением?


person Sushant Kulkarni    schedule 23.04.2017    source источник


Ответы (1)


Вам нужно изменить порядок values by column names, а где 0 заменить на mask на пустые строки:

df = df.set_index('id')

k = 3
vals = df.values
arr1 = np.argsort(-vals, axis=1)

print (vals[np.arange(len(df.index))[:,None], arr1][:,:k])
[[ 9  4  0]
 [ 4  0  0]
 [10  7  3]
 [ 5  3  1]
 [10  7  3]]

a = df.columns[arr1[:,:k]]
mask = vals[np.arange(len(df.index))[:,None], arr1][:,:k] == 0
print (mask)
[[False False  True]
 [False  True  True]
 [False False False]
 [False False False]
 [False False False]]

result = pd.DataFrame(a, columns=['top{}'.format(i) for i in range(1, k+1)],
                         index=df.index)

result = result.mask(mask, '')
print(result)
   top1 top2 top3
id               
1    p2   p4     
2    p4          
3    p3   p4   p2
4    p2   p3   p1
5    p4   p3   p2
person jezrael    schedule 23.04.2017