基于不均匀日期重新编制 pandas 数据框,然后使用groupby和blank填充某些值 [英] Reindex pandas dataframe based on uneven dates and then groupby and blank fill certain values

查看:125
本文介绍了基于不均匀日期重新编制 pandas 数据框,然后使用groupby和blank填充某些值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似这样的数据框:

df

 名称日期二进制
Apple 2016-04-24 MAM 1
香蕉2016-05-01 MAM 1
Berry 2016-05-01 MAM 1
Berry 2017- 11-05 OND 1
Orange 2016-11-27 OND 1
猕猴桃2017-03-27 MAM 1

我有一个日期时间对象,如下所示:

df1

 日期星期
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

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



我需要的是有点复杂。我需要一个函数或算法来识别 df.date 作为结束日期和 df1.date 作为开始日期某些季节。换句话说, df 中的Apple事件在2016-04-24开始,由 binary = 1 。在新的数据框中,我需要包含2016-04-24之前的几周,但在2016-03-28之后,添加一个名为 binary = 0 的列,因为事件已经还没有发生。



乱七八糟的事情是,有四个季节:MAM 2016,OND 2016,MAM 2017和OND 2017.每个开始日期只应考虑该季节的 df.date



举例来说,这就是我期望得到的结果:



df_result

 名称日期季节二进制
苹果2016-03-28 MAM 0
苹果2016-04-04 MAM 0
苹果2016-04-11 MAM 0
苹果2016-04-18 MAM 0
苹果2016-04-24 MAM 1
香蕉2016-03-28 MAM 0
香蕉2016-04-04 MAM 0
香蕉2016-04-11 MAM 0
香蕉2016-04-18 MAM 0
香蕉2016-04-25 MAM 0
香蕉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
橙色2016-10-03 OND 0
橙色2016-10-10 OND 0
橙色2016-10-17 OND 0
橙色2016-10-24 OND 0
橙色2016-10-31 OND 0
橙色2016-11-07 OND 0
橙色2016-11-14 OND 0
橙色2016-11-21 OND 0
Orange 2016-11-27 OND 1
猕猴桃2017-03-13 MAM 0
猕猴桃2017-03-20 MAM 0
猕猴桃2017-03-27 MAM 1

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


  • MAM 2016:2016-03-28至2016-06-13

  • OND 2016:2016-10-03至2016-11-21

  • MAM 2017:2017-03-13至2017-09-25

  • OND 2017:2017-10-02至2017-11-20



借助一些帮助,我知道我应该reindex df df2 = df.reindex(start_end_dates)类似的东西,但这不起作用那么我应该在 df.date 之前几周将名称和填充空白填充为0。 。所以也许: df3 = df3.loc [df3.groupby(level = 0).binary.bfill()。dropna()。index] .fillna(0).reset_index()



我已经看到了这个堆栈溢出问题,但它并不完全回答我的问题: Reindex pandas DataFrame来填补遗漏日期



非常感谢。

解决方案

我们使用 merge_asof

b $ b

  df ['Year'] = df ['date']。dt.year 
df1 ['Year'] = df1 ['date']。 dt.year
A = []
,范围为len(len(df)):
Temp = pd.merge_asof(df1.sort_values('date'),df.sort_values(' ()','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'])


目标
输出[262]:
名称年份二进制日期季节
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香蕉2016 NaN 2016-03-28 MAM
1香蕉2016 NaN 2016-04- 04 MAM
2 Banana 2016 NaN 2016-04-11 MAM
3香蕉2016 NaN 2016-04-18 MAM
4香蕉2016 NaN 2016-04-25 MAM
1香蕉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猕猴桃2017 NaN 2017-03-13 MAM
21猕猴桃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橙色2016 NaN 2016-10-17 OND
15橙色2016 NaN 2016-10-24 OND
16橙色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


I have a dataframe that looks something like this:

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

And I have a long date time object of a bunch of dates like this:

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

where Week is dtype: object, date is dtype: datetime64[ns], and season is dtype: object.

What I need is a bit complicated. I need a function or algorithm that recognizes df.date as the "end date" and df1.date as the "start date" for certain seasons. In other words, an event for "Apple" in df started on 2016-04-24 which is indicated by the binary=1. In a new dataframe, I need to include the weeks before 2016-04-24 but after 2016-03-28 and add a column that says binary=0 because the event had not occurred yet.

The messy thing is that there a four seasons: MAM 2016, OND 2016, MAM 2017, and OND 2017. And the "start date" for each df.date should only be considered for that season.

As an example, this is what I'm looking to get:

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

To summarize the seasons in start_end_dates and make it a little clearer, these are the dates:

  • MAM 2016: 2016-03-28 to 2016-06-13
  • OND 2016: 2016-10-03 to 2016-11-21
  • MAM 2017: 2017-03-13 to 2017-09-25
  • OND 2017: 2017-10-02 to 2017-11-20

With some help, I know that this I should reindex df with something like df2 = df.reindex(start_end_dates) but this doesn't work out quite right.

Then I should groupby the names and blank fill with "0" the weeks before df.date. So maybe: df3 = df3.loc[df3.groupby(level=0).binary.bfill().dropna().index].fillna(0).reset_index()

I have seen this stack overflow question but it doesn't exactly answer my question: Reindex pandas DataFrame to fill missing dates

Help greatly appreciated.

解决方案

We using 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

这篇关于基于不均匀日期重新编制 pandas 数据框,然后使用groupby和blank填充某些值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆