Фрейм данных: как мне найти значение в одном столбце для квантиля во втором столбце

#python #pandas #quantile

#python #pandas #квантиль

Вопрос:

У меня есть фрейм данных, показанный ниже, с датами, смещением и количеством.

например, это начало фрейма данных

 df = pd.DataFrame(np.array([['2018-01-01', 0, 1], ['2018-01-01', 26, 2], ['2018-01-01', 178, 8], ['2018-01-01', 187, 10], ['2018-01-01', 197, 13], ['2018-01-01', 208, 15], ['2018-01-01', 219, 16], ['2018-01-01', 224, 19],['2018-01-01', 232, 21], ['2018-01-01', 233, 25], ['2018-01-01', 236, 32],['2018-01-02', 0, 1], ['2018-01-02', 11, 4], ['2018-01-02', 12, 7], ['2018-01-02', 20, 12], ['2018-01-02', 35, 24], ]), columns=['obs_date', 'offset', 'count'])

    obs_date    offset  count
0   2018-01-01  0       1
1   2018-01-01  26      2
2   2018-01-01  178     8
3   2018-01-01  187     10
4   2018-01-01  197     13
5   2018-01-01  208     15
6   2018-01-01  219     16
7   2018-01-01  224     19
8   2018-01-01  232     21
9   2018-01-01  233     25
10  2018-01-01  236     32
11  2018-01-02  0       1
12  2018-01-02  11      4
13  2018-01-02  12      7
14  2018-01-02  20      12
15  2018-01-02  35      24
  

и т. Д

Я хотел бы получить (совокупный) квантиль [‘count’] [0.25, 0.5, 0.75] для каждой даты и найти строку с [‘offset’], к которой применяется этот квантиль. общее количество для каждой даты будет разным, а смещения не являются регулярными, поэтому для 2018-01-01 дата и смещение, соответствующие количеству 8, 16 amp; 24 (0.25, 0.5, 0.75 * 32)

что-то вроде

 0   2018-01-01  178     0.25
1   2018-01-01  219     0.5
2   2018-01-01  232.75  0.75
3   2018-01-02  43      0.25
etc     
  

Комментарии:

1. Я в замешательстве. Вы хотите установить квантиль на основе какого столбца? И какой столбец является суммой?

Ответ №1:

У меня это сработало:

 df['count'] = df['count'].astype(int)
quantiles = [.25, .5, .75]

def get_offset(x):
    s = x['count']
    indices = [(s.sort_values()[::-1] <= s.quantile(q)).idxmax() for q in quantiles]
    return df.iloc[indices, x.columns.get_loc('offset')]

res = df.groupby('obs_date').apply(get_offset).reset_index(level=0)
  

Тогда вы можете concat с помощью квантилей:

 pd.concat([res.reset_index(drop=True), pd.Series(quantiles * df.obs_date.nunique())], axis=1)

    obs_date    offset  0
0   2018-01-01  178     0.25
1   2018-01-01  208     0.50
2   2018-01-01  224     0.75
3   2018-01-02  11      0.25
4   2018-01-02  12      0.50
5   2018-01-02  20      0.75
  

Комментарии:

1. спасибо, но выглядит не совсем правильно — я бы ожидал, что строка 2 будет читать 232 или 233, поскольку Q3 находится между строками 8/9 — это на самом деле не квантиль (), поскольку я ищу значение 0,75 * 32, а не значение, которое составляет 3/4 пути по списку, этот код дает мне хорошее начало, поэтому я ожидаю создать столбец max_count и столбец пропорций (count / max_count) и найти значения, используя idmax таким образом?

2. незначительный мод — добавлен столбец max_count и из него получен df [‘propn’] = df ‘[count’] / df [‘max_count’] . из этого строки get_offset являются просто s = x [‘propn’] indexes = [(s.sort_values()[:: -1] <= q).idxmax() для q в квантилях].

3. Да, я заметил, что мои значения были немного отклонены. Я видел, что вы приняли ответ, спасибо! Итак, с этим разобрались?

4. Это было очень полезно, спасибо — дало мне структуру, необходимую для ее разработки — для тех, кто придет позже — не нуждался . метод quartile (), поскольку это совокупный подсчет, а не наблюдения

5. отлично 🙂 не стесняйтесь редактировать мой ответ или публиковать свой собственный