DataFrame: как да намеря стойност в една колона за квантил във втора колона

Имам DataFrame, показан по-долу с дати, отместване и брой.

например, това е началото на рамката с данни

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 и 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     

person CestLaGalere    schedule 06.03.2019    source източник
comment
Объркан съм. Искате да зададете квантил въз основа на коя колона? И коя колона cumsum?   -  person Mohit Motwani    schedule 06.03.2019


Отговори (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
person Josh Friedlander    schedule 06.03.2019
comment
благодаря, но не изглежда съвсем правилно - очаквам ред 2 да прочете 232 или 233, тъй като Q3 е между ред 8/9 - всъщност не е квантил(), тъй като търся стойността 0,75 * 32, а не стойността това е 3/4 от пътя през списъка, този код ми дава добър старт, така че очаквам да създам колона max_count и колона пропорция (count / max_count) и да намеря стойностите, използвайки idmax по този начин? - person CestLaGalere; 06.03.2019
comment
второстепенна модификация - добавена колона max_count и от нея извлечен df['propn'] = df'[count'] / df['max_count']. от това редовете на get_offset са просто s = x['propn'] индекси = [(s.sort_values()[::-1] ‹= q).idxmax() за q в квантили]. - person CestLaGalere; 06.03.2019
comment
Да, забелязах, че стойностите ми са малко по-различни. Видях, че сте приели отговора, благодаря! Тогава подредено ли е? - person Josh Friedlander; 06.03.2019
comment
Беше много полезно, благодаря - даде ми структурата, от която се нуждаех, за да го разработя - за всеки, който дойде по-късно - нямах нужда от метода .quartile(), тъй като това е кумулативен брой, а не наблюдения - person CestLaGalere; 06.03.2019
comment
страхотно :) не се колебайте да редактирате моя отговор или да публикувате свой собствен - person Josh Friedlander; 07.03.2019