2017-03-16 69 views
1

我有一個城市名稱的熊貓數據幀和日期如下: Python的大熊貓 - 矢量化的自定義功能,而不是適用

In[34]: df.head(6) 
Out[34]: 
     CITY  DATE 
0 LONDON 2017-03-12 
1 LONDON 2017-03-12 
2  PARIS 2014-05-05 
3  PARIS 2017-03-12 
4 LONDON 2017-03-12 
5 NEW-YORK 2017-03-12 

我也有另外一個數據幀匹配一個人的城市給定的時間範圍(這基本上是說這個人在開始日期和結束日期之間的城市)

In[51]: db.head() 
Out[51]: 
     CITY PERSON  START   END 
0  PARIS ID4 2014-01-01 2017-03-16 
1 NEW-YORK ID5 2014-01-07 2016-12-31 
2 LONDON ID1 2014-01-01 2016-05-08 
3 MONTREAL ID1 2016-05-09 2017-03-16 
4  TOKYO ID5 2017-01-01 2017-03-16 

我想將列添加到df,以確定這是人在給定的城市爲給定的每一行日期。

我能夠使用自定義函數myfunc實現它,我使用df.apply(lambda x: myfunc(x['CITY'], x['DATE']), axis=1)將行應用到df

myfunc簡單地識別db正確PERSON如下:

def myfunc(city, date): 
    return db.loc[(db.CITY==city) & (db.START <= date) & (db.END >= date), 'PERSON'].values[0] 

這種運作良好,但它是非常大的dataframes相當緩慢......我試圖在db數據以某種方式合併到df或至少在不依賴行方式實現的情況下實現我所做的矢量化版本。 有什麼幫助嗎?

回答

3

使用pd.merge_asof

  • df必須'DATE'
  • db進行排序必須由'START'然後進行排序由'END'
  • 我們使用by參數只能由'CITY'
  • query在匹配結束以確保我們只得到'END' >= 'DATE'

pd.merge_asof(
    df.sort_values('DATE'), 
    db.sort_values(['START', 'END']), 
    left_on='DATE', right_on='START', by='CITY' 
).query('DATE <= END') 

    CITY  DATE PERSON  START  END 
0 PARIS 2014-05-05 ID4 2014-01-01 2017-03-16 
3 PARIS 2017-03-12 ID4 2014-01-01 2017-03-16 

注意,只有'PARIS'條目與您所提供的數據進行匹配。