Reindex pandas数据框基于不均匀的日期,然后groupby和blank填充某些值

时间:2017-12-07 16:24:27

标签: python pandas dataframe indexing group-by

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

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作为"开始日期"某些季节。换句话说,一场'" Apple" df中的binary=1已于2016-04-24开始,由binary=0表示。在新的数据框架中,我需要包括2016-04-24之前的几周,但是在2016-03-28之后,添加一个显示df.date的列,因为事件尚未发生。

杂乱无章的是有四季:MAM 2016,OND 2016,MAM 2017和OND 2017."开始日期"对于每个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 ,只应考虑该季节。

举个例子,这就是我想要的:

df_result

start_end_dates

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

  • 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

在一些帮助下,我知道我应该使用类似df2 = df.reindex(start_end_dates)的内容重新标记df.date,但这并不是很正确。

然后我应该用名称和空白填充" 0" df3 = df3.loc[df3.groupby(level=0).binary.bfill().dropna().index].fillna(0).reset_index()前几周。也许:from setuptools import setup, find_packages setup( name = 'EU-Crawler', version = '1.0', packages = find_packages(), scripts = [ 'bin/launcher.py', 'bin/DE_WEB_launcher.py', 'bin/ES_WEB_launcher.py', 'bin/FR_WEB_launcher.py', 'bin/IT_WEB_launcher.py', 'bin/NL_WEB_launcher.py', 'bin/DE_MOBILE_launcher.py', 'bin/FR_MOBILE_launcher.py' ], package_data = { 'Crawling': ['*.ini'], }, entry_points = {'scrapy': ['settings = Crawling.settings']}, install_requires=[ 'scrapy-crawlera>=1.2.2', 'configobj', 'scrapy-fake-useragent', 'xmltodict', 'selenium==2.53.2', 'python-dateutil', 'pyvirtualdisplay', 'beautifulsoup4', 'incapsula-cracker-py3' ], extras_require={'ScrapyElasticSearch': 'ScrapyElasticSearch[extras]'}, zip_safe = False, include_package_data=True )

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

非常感谢。

1 个答案:

答案 0 :(得分: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