Панды: извлекать первые три идентификатора на основе значений в другом столбце за предыдущий день - PullRequest
0 голосов
/ 06 февраля 2019

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

date_test = pd.DataFrame({
    'id': ['q','w','e','r','t','y',
           'a','s','d','f','g',
           'z','x',
           'b','n','m','k'],
    'metric': [123,122,45,31,5,2,
               634,372,312,229,110,
               434,334,
               256,156,44,23],
    'date':['2019-11-01','2019-11-01','2019-11-01','2019-11-01','2019-11-01', '2019-11-01', 
             '2019-11-02','2019-11-02','2019-11-02','2019-11-02','2019-11-02',
             '2019-11-04','2019-11-04',
            '2019-11-05','2019-11-05','2019-11-05','2019-11-05']
    })

Он был отсортирован по date и metric.Сложность в том, что у меня есть пробелы в датах, поэтому я не могу рассчитать previous на основе даты.Для каждой даты мне нужно захватить топ-3 id с.Если в предыдущий день было меньше id с, я должен использовать top_1.Первая дата должна быть заполнена NaN, так как нет предыдущего периода для просмотра.Результат должен выглядеть следующим образом:

    id  metric  date        top_1   top_2   top_3
0   q   123     2019-11-01  None    None    None
1   w   122     2019-11-01  None    None    None
2   e   45      2019-11-01  None    None    None
3   r   31      2019-11-01  None    None    None
4   t   5       2019-11-01  None    None    None
5   y   2       2019-11-01  None    None    None
6   a   634     2019-11-02  q       w       e
7   s   372     2019-11-02  q       w       e
8   d   312     2019-11-02  q       w       e
9   f   229     2019-11-02  q       w       e
10  g   110     2019-11-02  q       w       e
11  z   434     2019-11-04  a       s       d
12  x   334     2019-11-04  a       s       d
13  b   256     2019-11-05  z       x       z
14  n   156     2019-11-05  z       x       z
15  m   44      2019-11-05  z       x       z
16  k   23      2019-11-05  z       x       z

Я буду очень признателен за вашу помощь!

1 Ответ

0 голосов
/ 06 февраля 2019

Я должен сделать некоторые предположения здесь.Непонятно, что бы вы хотели сделать, если бы был галстук.Я бы также сделал отдельный фрейм данных для хранения результатов.

# Date should be a datetime
date_test['date'] = pd.to_datetime(date_test['date'])

# Initialize a place to store results
min_date = date_test['date'].min()
max_date = date_test['date'].max()
solution = pd.DataFrame(index=pd.DatetimeIndex(start=min_date,end=max_date,freq='d'))

# Iterate for results
for i in solution.index:
    mask = date_test['date'] == i
    vals = date_test[mask].sort_values('metric',ascending=False)['id'].values[:3]

    # Store results if found
    for j in range(min([3,vals.shape[0]])):
        solution.loc[i,'top_%i'%(j+1)]=vals[j]

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

Я добавляю некоторую информацию на основе комментария.

Если вы хотите заполнить значения.Вы можете использовать pd.fillna().Приведенный ниже код заполнит значения NA последней доступной датой.

 solution.fillna(method='ffill',inplace=True)
...