Обновите значения в кадре данных для каждого n-го значения с помощью группы - PullRequest
0 голосов
/ 23 октября 2019

У меня есть фрейм данных, для которого я хотел бы заполнить некоторые значения в 'snail_chart_dates' без использования цикла.

Значения, которые я хотел бы, это первый 'value_date' и последний 'value_date' исреднее значение «value_date», сгруппированное по code_id

Я думаю, что это можно сделать, возможно, с помощью комбинации .iloc[0] и .iloc[-1], но я понятия не имею, как применить это к groupby или как получитьсредний

Пример урезанного фрейма данных - другой намного длиннее

enter image description here

    import pandas as pd
    import numpy as np 

    returns = pd.DataFrame({
            'value_date' : ['2018-01-31', '2018-02-28', '2018-03-31','2018-04-30', '2018-05-31', '2018-06-30', 
                            '2018-01-31', '2018-02-28', '2018-03-31','2018-04-30', '2018-05-31', '2018-06-30'],
            'code_id' :  ['AUD','AUD','AUD','AUD','AUD','AUD', 
                          'USD','USD','USD','USD','USD','USD'],
            'gross_return': [.01, .02, .03, -.4, -.06, -.02, 
                             .06, .8, .9, .4, -1.06, .03],
            'bm_return': [.01, .02, .03, -.4, -.06, -.02, 
                             .06, .8, .9, .4, -1.06, .03],
            })


    returns["snail_chart_dates"] = ""

пример желаемого результата - без середины

enter image description here

Ответы [ 2 ]

1 голос
/ 23 октября 2019

Сначала мы получаем min и max дату для группы.

Затем мы получаем индексы этих значений для группы с idxmin и idxmax.

ToПолучив средние значения, мы получаем median индекса для каждой группы и round up с np.ceil

И, наконец, мы присваиваем эти значения нашему новому столбцу с помощью loc:

grp = returns.groupby('code_id')
s1 = grp['value_date'].transform('min')
s2 = grp['value_date'].transform('max')
s3 = grp.apply(lambda x: np.ceil(np.median(x.index))).values

idx_min = grp['value_date'].idxmin().values
idx_max = grp['value_date'].idxmax().values

returns.loc[idx_min, 'snail_chart_dates'] = s1.loc[idx_min]
returns.loc[idx_max, 'snail_chart_dates'] = s2.loc[idx_max]
returns.loc[s3, 'snail_chart_dates'] = returns.loc[s3, 'value_date']

   value_date code_id  gross_return  bm_return snail_chart_dates
0  2018-01-31     AUD          0.01       0.01        2018-01-31
1  2018-02-28     AUD          0.02       0.02               NaT
2  2018-03-31     AUD          0.03       0.03               NaT
3  2018-04-30     AUD         -0.40      -0.40        2018-04-30
4  2018-05-31     AUD         -0.06      -0.06               NaT
5  2018-06-30     AUD         -0.02      -0.02        2018-06-30
6  2018-01-31     USD          0.06       0.06        2018-01-31
7  2018-02-28     USD          0.80       0.80               NaT
8  2018-03-31     USD          0.90       0.90               NaT
9  2018-04-30     USD          0.40       0.40        2018-04-30
10 2018-05-31     USD         -1.06      -1.06               NaT
11 2018-06-30     USD          0.03       0.03        2018-06-30
0 голосов
/ 23 октября 2019

Если вы поместите value_date в формат даты и времени Pandas, есть очень простое решение.

Мы можем сгруппировать по коду и использовать функцию .quantile() для получения наших дат.

returns["value_date"] = pd.to_datetime(returns["value_date"])
code_groups = returns.groupby("code_id")["value_date"]
code_groups.quantile(0, interpolation="nearest")
code_id
AUD   2018-01-31
USD   2018-01-31
Name: value_date, dtype: datetime64[ns]
code_groups.quantile(0.5, interpolation="nearest")
code_id
AUD   2018-03-31
USD   2018-03-31
Name: value_date, dtype: datetime64[ns]

Затем вы можете назначить эту информацию по своему усмотрению в таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...