Найти максимальную частоту для каждого Sequence_ID - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть датафрейм, например:

Time         Frq_1   Seq_1       Frq_2   Seq_2       Frq_3   Seq_3
12:43:04     -       30,668      -       30,670      4,620   30,671 
12:46:05     -       30,699      -       30,699      3,280   30,700 
12:46:17     4,200   30,700      -       30,704      -       30,704 
12:46:18     3,060   30,700      4,200   30,700      -       30,700 
12:46:18     3,060   30,700      4,200   30,700      -       30,700 
12:46:19     3,060   30,700      4,220   30,700      -       30,700 
12:46:20     3,060   30,700      4,240   30,700      -       30,700 
12:46:37     -       30,698      -       30,699      3,060   30,700 
12:46:38     -       30,699      3,060   30,700      4,600   30,700 
12:47:19     -       30,668      -       30,669      -       30,669 
12:47:20     -       30,667      -       30,667      -       30,668 
12:47:20     -       30,667      -       30,667      -       30,668 
12:47:21     -       30,667      -       30,667      -       30,668 
12:47:21     -       30,665      -       30,665      -       30,665 
12:47:22     -       30,665      -       30,665      -       30,665 
12:48:35     -       30,688      -       30,690      3,020   30,690 
12:49:29     4,160   30,690      -       30,691      -       30,693 

Я хочу проверить итоговый фрейм данных и найти результат с приведенным ниже условием:

  1. Sequence_ID, для которого частота не указанаnull
  2. Sequence_ID, для которого частота равна Max (в случае нескольких Sequence_ID с ненулевой частотой)

Я хочу получить свой результат, как показано ниже:

Time         Sequence_ID    Frequency
12:43:04     4,620          30,671 
12:46:18     4,200          30,700 
12:49:29     4,160          30,690 

Время = соответствует ряду (Sequence_ID & Frequency)

1 Ответ

2 голосов
/ 25 сентября 2019

Это оказалось довольно сложным.Здесь мы в любом случае:

long_df = pd.wide_to_long(df.reset_index(), stubnames=['Seq_', 'Frq_'], 
                          suffix='\d+', i='index', j='j')
long_df['Frq_'] = pd.to_numeric(long_df.Frq_.str.replace(',','.')
                                .replace('-',float('nan')))
long_df.reset_index(drop=True, inplace=True)
ix = long_df.groupby('Seq_').Frq_.idxmax()

print(long_df.loc[ix[ix.notna()].values.astype(int)])

     Time      Seq_   Frq_
34  12:43:04  30,671  4.62
16  12:49:29  30,690  4.16
42  12:46:38  30,700  4.60

Похоже на последовательность 30,700, самая высокая частота 4.60, а не 4.20


Первым шагом является сведение кадра данных в три строки: один для Time, другой для последовательности и частоты.Мы можем использовать pd.wide_to_long с именами-заглушками ['Seq_', 'Frq_']:

long_df = pd.wide_to_long(df.reset_index(), stubnames=['Seq_', 'Frq_'], 
                              suffix='\d+', i='index', j='j')

print(long_df)

            Time    Seq_   Frq_
index j                         
0     1  12:43:04  30,668      -
1     1  12:46:05  30,699      -
2     1  12:46:17  30,700  4,200
3     1  12:46:18  30,700  3,060
4     1  12:46:18  30,700  3,060
5     1  12:46:19  30,700  3,060
6     1  12:46:20  30,700  3,060
7     1  12:46:37  30,698      -
8     1  12:46:38  30,699      -
9     1  12:47:19  30,668      -
10    1  12:47:20  30,667      -
11    1  12:47:20  30,667      -
12    1  12:47:21  30,667      -
13    1  12:47:21  30,665      -
14    1  12:47:22  30,665      -
15    1  12:48:35  30,688      -
16    1  12:49:29  30,690  4,160
...

Следующим шагом является приведение типов с плавающей точкой к float, чтобы иметь возможность найти максимальные значения:

long_df['Frq_'] = pd.to_numeric(long_df.Frq_.str.replace(',','.')
                                    .replace('-',float('nan')))

print(long_df)

          Time    Seq_  Frq_
index j                        
0     1  12:43:04  30,668   NaN
1     1  12:46:05  30,699   NaN
2     1  12:46:17  30,700  4.20
3     1  12:46:18  30,700  3.06
4     1  12:46:18  30,700  3.06
5     1  12:46:19  30,700  3.06
6     1  12:46:20  30,700  3.06
7     1  12:46:37  30,698   NaN
... 

Затем мы можем сгруппировать Seq_ и найти индексы с самыми высокими значениями.Можно также подумать об использовании max, но это уберет столбец Time.

long_df.reset_index(drop=True, inplace=True)
ix = long_df.groupby('Seq_').Frq_.idxmax()

И, наконец, индекс, основанный на вышеприведенном:

print(long_df.loc[ix[ix.notna()].values.astype(int)])

     Time      Seq_   Frq_
34  12:43:04  30,671  4.62
16  12:49:29  30,690  4.16
42  12:46:38  30,700  4.60
...