Кадр данных Pandas, основанный на месяцах между столбцами даты и средним значением - PullRequest
1 голос
/ 11 апреля 2019

Я работаю с фреймом данных pandas, используя df.groupby (), который смог закончить, включая ['start_date'] и ['end_date'] и значение для определенного идентификатора.

| id         | start_date       | end_date       |value|
|:-----------|------------======|:---------------|-----|
| 1          |        02-01-2018|      05-31-2018|   40|
| 2          |        01-01-2018|      03-31-2018| 12.3|

Есть любой

И это тот фрейм данных, который я пытаюсь завершить: (значение равно значению / nummonths между start_date и конечной_date)

    |id          | month_belongs    | value|
    |------------|------------------|------|
    | 1          |        02-01-2018|    10|
    | 1          |        03-01-2018|    10|
    | 1          |        04-01-2018|    10|
    | 1          |        05-01-2018|    10|
    | 2          |        01-01-2018|   4.1|
    | 2          |        02-01-2018|   4.1|
    | 2          |        03-01-2018|   4.1|

Ответы [ 3 ]

2 голосов
/ 11 апреля 2019

Больше похоже на проблему unnesting, скрытый ключ был создан date_range

#df.start_date=pd.to_datetime(df.start_date,dayfirst=False)
#df.end_date=pd.to_datetime(df.end_date,dayfirst=False)
df['month_belongs']=[pd.date_range(x,y,freq='MS')for x , y in zip(df.start_date,df.end_date)]
df=unnesting(df,['month_belongs'])
df['value']/=df['value'].groupby(level=0).transform('size').values
df
Out[301]: 
  month_belongs  id start_date   end_date  value
0    2018-02-01   1 2018-02-01 2018-05-31   10.0
0    2018-03-01   1 2018-02-01 2018-05-31   10.0
0    2018-04-01   1 2018-02-01 2018-05-31   10.0
0    2018-05-01   1 2018-02-01 2018-05-31   10.0
1    2018-01-01   2 2018-01-01 2018-03-31    4.1
1    2018-02-01   2 2018-01-01 2018-03-31    4.1
1    2018-03-01   2 2018-01-01 2018-03-31    4.1

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([
        pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')
1 голос
/ 12 апреля 2019

Предпосылка: я новичок в панде и в основном в программировании.Я публикую свое решение больше, чтобы получить указания на лучшие способы сделать это, чем что-либо еще.Для меня было уже приятно иметь возможность добраться до этой точки, и я чувствовал, что код был по крайней мере достаточно чист, чтобы показать его (надеюсь, что все в порядке).Вероятно, мне придется потратить некоторое время на то, чтобы обернуться вокруг принятого ответа.

import pandas as pd
from datetime import datetime
from dateutil.relativedelta import relativedelta

start=[["02-01-2018", "05-31-2018", 40],
    ["01-01-2018", "03-31-2018", 12.3]]

df=pd.DataFrame(start,columns = ['std','end','v'])
df['std']=pd.to_datetime(df['std'])
df['end']=pd.to_datetime(df['end'])
df2=pd.DataFrame(columns = ['id', 'month_belongs', 'value'])
ix=0 # I'm sure there must be a better way here, than needing an index
for index, row in df.iterrows():
    e,s =row['end'], row['std']
    difference = relativedelta(e, s)
    months = difference.months+1
    while s <= e:
        df2.loc[ix]=[index,s,row['v']/months]
        s+= relativedelta(months=1)
        ix+=1
print(df2)

вывод:

  id month_belongs  value
0  0    2018-02-01   10.0
1  0    2018-03-01   10.0
2  0    2018-04-01   10.0
3  0    2018-05-01   10.0
4  1    2018-01-01    4.1
5  1    2018-02-01    4.1
6  1    2018-03-01    4.1
0 голосов
/ 11 апреля 2019
import pandas as pd

df["value"] = df.apply(
    lambda x: x["value"]/(
        (pd.to_datetime(x["end_date"]) + pd.Timedelta(days=1)).month -
        pd.to_datetime(x["start_date"]).month), 
    axis=1
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...