根据不均匀的日期重新索引熊猫数据框,然后用 groupby 和空白填充某些值

Posted

技术标签:

【中文标题】根据不均匀的日期重新索引熊猫数据框,然后用 groupby 和空白填充某些值【英文标题】:Reindex pandas dataframe based on uneven dates and then groupby and blank fill certain values 【发布时间】:2018-05-21 19:41:14 【问题描述】:

我有一个看起来像这样的数据框:

df

Name    date          season  binary
Apple   2016-04-24    MAM     1
Banana  2016-05-01    MAM     1
Berry   2016-05-01    MAM     1
Berry   2017-11-05    OND     1
Orange  2016-11-27    OND     1
Kiwi    2017-03-27    MAM     1

我有一个长日期时间对象,包含这样的一堆日期:

df1

date        season  Week
2016-03-28  MAM     13
2016-04-04  MAM     14
2016-04-11  MAM     15
2016-04-18  MAM     16
2016-04-25  MAM     17
2016-05-02  MAM     18
2016-05-09  MAM     19
2016-05-16  MAM     20
2016-05-23  MAM     21
2016-05-30  MAM     22
2016-06-06  MAM     23
2016-06-13  MAM     24
2016-10-03  OND     40
2016-10-10  OND     41
2016-10-17  OND     42
2016-10-24  OND     43
2016-10-31  OND     44
2016-11-07  OND     45
2016-11-14  OND     46
2016-11-21  OND     47
2017-03-13  MAM     11
2017-03-20  MAM     12
2017-03-27  MAM     13
2017-04-03  MAM     14
2017-04-10  MAM     15
2017-04-17  MAM     16
2017-04-24  MAM     17
2017-05-01  MAM     18
2017-05-08  MAM     19
2017-05-15  MAM     20
2017-05-22  MAM     21
2017-05-29  MAM     22
2017-06-19  MAM     25
2017-06-26  MAM     26
2017-07-03  MAM     27
2017-07-10  MAM     28
2017-07-17  MAM     29
2017-07-24  MAM     30
2017-07-31  MAM     31
2017-08-07  MAM     32
2017-08-14  MAM     33
2017-08-21  MAM     34
2017-08-28  MAM     35
2017-09-04  MAM     36
2017-09-11  MAM     37
2017-09-18  MAM     38
2017-09-25  MAM     39
2017-10-02  OND     40
2017-10-09  OND     41
2017-10-16  OND     42
2017-10-23  OND     43
2017-10-30  OND     44
2017-11-06  OND     45
2017-11-13  OND     46
2017-11-20  OND     47

其中Week 是dtype: object,date 是dtype: datetime64[ns],season 是dtype: object。

我需要的有点复杂。我需要一个函数或算法,将df.date 识别为“结束日期”,将df1.date 识别为某些季节的“开始日期”。换句话说,df 中的“Apple”事件始于 2016 年 4 月 24 日,由binary=1 表示。在一个新的数据框中,我需要包含 2016-04-24 之前但 2016-03-28 之后的几周,并添加一列 binary=0,因为该事件尚未发生。

麻烦的是有四个季节:MAM 2016、OND 2016、MAM 2017 和 OND 2017。每个 df.date 的“开始日期”应该只考虑那个季节。

作为一个例子,这就是我想要得到的:

df_result

Name    date          season  binary
Apple   2016-03-28    MAM     0
Apple   2016-04-04    MAM     0
Apple   2016-04-11    MAM     0
Apple   2016-04-18    MAM     0
Apple   2016-04-24    MAM     1
Banana  2016-03-28    MAM     0
Banana  2016-04-04    MAM     0
Banana  2016-04-11    MAM     0
Banana  2016-04-18    MAM     0
Banana  2016-04-25    MAM     0
Banana  2016-05-01    MAM     1
Berry   2016-03-28    MAM     0
Berry   2016-04-04    MAM     0
Berry   2016-04-11    MAM     0
Berry   2016-04-18    MAM     0
Berry   2016-04-25    MAM     0
Berry   2016-05-01    MAM     1
Berry   2017-10-02    OND     0
Berry   2017-10-09    OND     0
Berry   2017-10-16    OND     0
Berry   2017-10-23    OND     0
Berry   2017-10-30    OND     0
Berry   2017-11-05    OND     1
Orange  2016-10-03    OND     0
Orange  2016-10-10    OND     0
Orange  2016-10-17    OND     0
Orange  2016-10-24    OND     0
Orange  2016-10-31    OND     0
Orange  2016-11-07    OND     0
Orange  2016-11-14    OND     0
Orange  2016-11-21    OND     0
Orange  2016-11-27    OND     1
Kiwi    2017-03-13    MAM     0
Kiwi    2017-03-20    MAM     0
Kiwi    2017-03-27    MAM     1

总结start_end_dates 中的季节并使其更加清晰,这些是日期:

2016 年 MAM:2016 年 3 月 28 日至 2016 年 6 月 13 日 2016 年起:2016 年 10 月 3 日至 2016 年 11 月 21 日 MAM 2017:2017-03-13 至 2017-09-25 2017 年起:2017 年 10 月 2 日至 2017 年 11 月 20 日

在一些帮助下,我知道我应该用df2 = df.reindex(start_end_dates) 之类的东西重新索引df,但这并不完全正确。

然后我应该在df.date 的前几周按名称分组并用“0”填充。所以也许:df3 = df3.loc[df3.groupby(level=0).binary.bfill().dropna().index].fillna(0).reset_index()

我已经看到这个堆栈溢出问题,但它并没有完全回答我的问题:Reindex pandas DataFrame to fill missing dates

非常感谢您的帮助。

【问题讨论】:

为什么猕猴桃只有两排,应该多吗? 你是对的。猕猴桃应该有三排。我将编辑问题。 @文 【参考方案1】:

我们使用merge_asof

df['Year']=df['date'].dt.year
df1['Year']=df1['date'].dt.year
A=[]
for x in range(len(df)):
    Temp=pd.merge_asof(df1.sort_values('date'),df.sort_values('date').iloc[[x],:],on='date',by=['Year','season'],direction='forward',allow_exact_matches =False).dropna().drop('Week',1)
    Temp.binary=np.nan
    A.append(Temp)
A.append(df)
target=pd.concat(A).sort_values(['Name','date'])


target
Out[262]: 
      Name  Year  binary       date season
0    Apple  2016     NaN 2016-03-28    MAM
1    Apple  2016     NaN 2016-04-04    MAM
2    Apple  2016     NaN 2016-04-11    MAM
3    Apple  2016     NaN 2016-04-18    MAM
0    Apple  2016     1.0 2016-04-24    MAM
0   Banana  2016     NaN 2016-03-28    MAM
1   Banana  2016     NaN 2016-04-04    MAM
2   Banana  2016     NaN 2016-04-11    MAM
3   Banana  2016     NaN 2016-04-18    MAM
4   Banana  2016     NaN 2016-04-25    MAM
1   Banana  2016     1.0 2016-05-01    MAM
0    Berry  2016     NaN 2016-03-28    MAM
1    Berry  2016     NaN 2016-04-04    MAM
2    Berry  2016     NaN 2016-04-11    MAM
3    Berry  2016     NaN 2016-04-18    MAM
4    Berry  2016     NaN 2016-04-25    MAM
2    Berry  2016     1.0 2016-05-01    MAM
47   Berry  2017     NaN 2017-10-02    OND
48   Berry  2017     NaN 2017-10-09    OND
49   Berry  2017     NaN 2017-10-16    OND
50   Berry  2017     NaN 2017-10-23    OND
51   Berry  2017     NaN 2017-10-30    OND
3    Berry  2017     1.0 2017-11-05    OND
20    Kiwi  2017     NaN 2017-03-13    MAM
21    Kiwi  2017     NaN 2017-03-20    MAM
5     Kiwi  2017     1.0 2017-03-27    MAM
12  Orange  2016     NaN 2016-10-03    OND
13  Orange  2016     NaN 2016-10-10    OND
14  Orange  2016     NaN 2016-10-17    OND
15  Orange  2016     NaN 2016-10-24    OND
16  Orange  2016     NaN 2016-10-31    OND
17  Orange  2016     NaN 2016-11-07    OND
18  Orange  2016     NaN 2016-11-14    OND
19  Orange  2016     NaN 2016-11-21    OND
4   Orange  2016     1.0 2016-11-27    OND

【讨论】:

太棒了!非常感谢。 @JAG2024 Yw~ ,愉快的编码,PS:不要害怕使用 for 循环,有时它比应用更快:-)

以上是关于根据不均匀的日期重新索引熊猫数据框,然后用 groupby 和空白填充某些值的主要内容,如果未能解决你的问题,请参考以下文章

熊猫数据框每天重新采样,没有日期时间索引

熊猫:挑选符合条件的人后重新索引

圆形熊猫日期时间索引?

如何在熊猫数据框中舍入日期时间索引?

带有日期索引的熊猫数据框->插入MySQL

如何在熊猫日期时间数据框中索引打开和关闭?