У меня есть несколько фреймов данных, все в одном формате:

i |nameA |  A  | nameB |  B  | nameC |  C  | nameD |  D
-------------------------------------------------------
0 |  1   | 45  |   9   | 123 |  123  |  23 |   1   | 502
1 |  5   | 435 |   15  | 894 |  523  | 1.1 |   5   | 502
2 |  10  | 112 |   20  | 542 |  234  |  52 |   7   | 502
3 |  7   | 432 |   2   | 900 |  43   | 653 |   4   | 502            
4 |  8   | 854 |   6   | 234 |  853  |  50 |   3   | 502
5 |  9   | 231 |   80  | 435 |  95   |  56 |   9   | 502

Я хочу найти максимальное и минимальное n значений для A, B, C, D, а также их индексы, чтобы я мог найти «имена», которые представляют собой целые числа от 0 до 3 цифр.

Из приведенного выше примера фрейма данных, если мне нужно максимум 4 значения, я бы хотел

(column, index, value, name):
(B, 3, 900, 2)
(B, 1, 894, 15)
(A, 4, 854, 8)
(C, 3, 653, 43)

И минимум 4 должен быть:

(column, index, value, name):
(C, 1, 1.1, 523)
(C, 0, 23, 123)
(A, 0, 45, 1)
(C, 4, 50, 853)

Не обязательно в этом формате.

Фрейм данных на самом деле никоим образом не сортируется, и имена не имеют никакой корреляции со значениями.

Любая помощь очень ценится, спасибо.

Изменить: заполнить пример фрейма данных и результатов.

-2
신동범 10 Окт 2021 в 12:53

2 ответа

Лучший ответ

Поскольку полного примера нет, вот один:

np.random.seed(0)
df = (pd.DataFrame(np.random.randint(0,100, size=(100, 8)),
                   columns=['nameA', 'A', 'nameB', 'B', 'nameC', 'C', 'nameD', 'D'])
        .rename_axis('i')
        .reset_index()
     )
>>> df.head()
   i  nameA   A  nameB   B  nameC   C  nameD   D
0  0     44  47     64  67     67   9     83  21
1  1     36  87     70  88     88  12     58  65
2  2     39  87     46  88     81  37     25  77
3  3     72   9     20  80     69  79     47  64
4  4     82  99     88  49     29  19     19  14

Теперь вы можете изменить форму и loc 4 значения nlargest для каждой группы:

(df.set_index('i')
   .set_axis(pd.MultiIndex.from_frame(df.columns[1:].str.extract('(^name)?(.+)').fillna('value'),
                                      names=[None, 'columns']
                                     ), axis=1)
   .stack(level='columns')
   .loc[lambda d: d.groupby('columns', group_keys=False)['value'].nlargest(4).index]
   .reset_index()
)

Выход:

     i columns  name  value
0    4       A    82     99
1   96       A    12     97
2   69       A    87     96
3   13       A    64     95
4   49       B    51     99
5   14       B     3     98
6   56       B    20     97
7   89       B    18     97
8    9       C    14     99
9   11       C    20     99
10  61       C    98     97
11  78       C    12     96
12  96       D    26     99
13  15       D     2     98
14  68       D    74     98
15  73       D    79     98
-1
mozway 10 Окт 2021 в 10:42

Вы можете использовать idxmax и idxmin, чтобы получить индекс (col i) максимума и минимума для каждого столбца.

df = pd.DataFrame({'i':[0,1,2],'nameA':[1,5,10],'A':[45,435,112]})
df.set_index('i',inplace = True)
df.A.idxmax()
1
-1
hkgyyf 10 Окт 2021 в 10:10