基于日期列之间的月份和平均值的熊猫数据框架

时间:2019-04-11 19:03:21

标签: python python-3.x pandas dataframe pandas-groupby

我正在使用df.groupby()处理一个熊猫数据框,它的结尾可以包括['start_date']和['end_date']以及特定ID的值。

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

这是试图以以下内容结尾的数据框:(值是start_date和end_date之间的value / nummonths)

    |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 个答案:

答案 0 :(得分:2)

更像是一个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 :(得分:1)

前提:我是熊猫的新手,而且也是编码的新手。我发布解决方案的目的更多,是获得比其他方法更好的指示。 对我而言,能够达到这一点已经很不错了,而且我认为代码至少足够干净可以显示出来(希望可以)。 我可能要花些时间把头放在接受的答案周围。

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

答案 2 :(得分:0)

<input type="text" th:field="*{featureArrayList[__${stat.index}__].name}"/>