根据来自另一个DataFrame的条件过滤熊猫中的DataFrame

时间:2019-03-25 16:41:59

标签: python pandas

我有两个数据帧,一个具有数百万行的数据,另一个具有仅几百个记录,并且我需要从第二个数据帧中筛选出三列。

因此,基本上,我需要遍历df2中的每一行,并查看df1中是否有任何行在开始日期和结束日期之间具有相同的代码和日期。可悲的是,我不知道如何使用python执行此操作。

所以我的数据框类似于以下内容

     Ticker    date
1    AA       2013-12-31 
3    AA       2015-02-28 
4    AA       2016-03-31 
5    AA       2016-04-30 
6    BB       2014-05-31 
7    BB       2014-06-30 
8    BB       2017-07-31 
9    CC       2014-08-31 
10   CC       2017-09-30 
11   CC       2018-10-31 
12   CC       2018-11-30 
13   DD       2018-11-30 
14   DD       2018-12-21

第二个:

     Ticker    StartDate   EndDate
1    AA       2016-01-01   2017-01-01
2    BB       2014-01-01   2015-01-01
3    CC       2018-01-01   2019-01-01
4    AA       2013-01-01   2014-01-01

我的预期结果是过滤第一个数据帧,其中包含开始日期和结束日期之间df2中所有股票的所有记录:

   Ticker     date
1    AA       2013-12-31  
2    AA       2016-03-31 
3    AA       2016-04-30 
4    BB       2014-05-31 
5    BB       2014-06-30  
6    CC       2018-11-30 

UPD

所以我尝试了以下方法:

df4 = pd.DataFrame()
###create empty dataframe
for index, row in df2.iterrows():
    df3 =df1.loc[(df1['DATE']>=row['StartDate'])&(df1['DATE']<=row['EndDate'])&(df1['Ticker'] ==row['Ticker'])]
###Go through rows of dataframe2, for every row i look if there any rows in df1 that falls under criteria 
    df4 = df4.append(df3)
### append filtered results of one row to empty dataframe 

它可以工作,但是要花一些时间-我尝试过滤掉2%的数据,大约花了25分钟

有什么办法可以加快速度吗?

2 个答案:

答案 0 :(得分:0)

尝试一下:

df3 = df1.merge(df2)
df3 =df3.loc[(df3['date']>=df3['StartDate'])&(df3['date']<=df3['EndDate'])]
df3.drop(['date'], axis = 1)

答案 1 :(得分:0)

您似乎可以通过为每个股票行情记录创建日期范围来使用分组依据

data = pd.read_clipboard()
flt_df = pd.read_clipboard()

数据

   Ticker        date
1      AA  2013-12-31
3      AA  2015-02-28
4      AA  2016-03-31
5      AA  2016-04-30
6      BB  2014-05-31
7      BB  2014-06-30
8      BB  2017-07-31
9      CC  2014-08-31
10     CC  2017-09-30
11     CC  2018-10-31
12     CC  2018-11-30
13     DD  2018-11-30
14     DD  2018-12-21

flt_df

  Ticker   StartDate     EndDate
1     AA  2016-01-01  2017-01-01
2     BB  2014-01-01  2015-01-01
3     CC  2018-01-01  2019-01-01
4     AA  2013-01-01  2014-01-01

grouped_df = flt_df.groupby('Ticker').agg({'StartDate':'min','EndDate':'max'})
merged = data.set_index('Ticker').join(grouped_df)
merged = merged[(merged.date>=merged.StartDate)&(merged.date<=merged.EndDate)]
merged.drop(['StartDate','EndDate'],axis=1,inplace=True)

合并

              date
Ticker            
AA      2013-12-31
AA      2015-02-28
AA      2016-03-31
AA      2016-04-30
BB      2014-05-31
BB      2014-06-30
CC      2018-10-31
CC      2018-11-30