2017-06-20 79 views
3

我有兩個帶有日期時間索引的數據幀。使用日期時間索引的部分連接數據幀

import pandas as pd 

d = {'dat': ['2016-01-01', '2016-01-02', '2016-01-03', '2017-01-01', '2017-01-02', '2017-01-03'],'x': [1, 2, 3, 4, 5, 6]} 
df1 = pd.DataFrame(d) 
df1.set_index(['dat'], inplace=True) 
df1.index = pd.to_datetime(df1.index) 

d = {'dat': ['2016-01-01', '2017-01-01'],'y': [10, 11]} 
df2 = pd.DataFrame(d) 
df2.set_index(['dat'], inplace=True) 
df2.index = pd.to_datetime(df2.index) 

DF1:

  x 
dat   
2016-01-01 1 
2016-01-02 2 
2016-01-03 3 
2017-01-01 4 
2017-01-02 5 
2017-01-03 6 

DF2:

   y 
dat   
2016-01-01 10 
2017-01-01 11 

我想只用年份和月份該指數的部分加入他們的行列。 所以輸出將類似於以下內容:

DF3:

  x y 
dat   
2016-01-01 1 10 
2016-01-02 2 10 
2016-01-03 3 10 
2017-01-01 4 11 
2017-01-02 5 11 
2017-01-03 6 11 

我試圖使用

df1.join(df2, how='inner') 

加入他們,我知道我可以提取年份和月份部分,像這樣:

df1.index.map(lambda x: x.strftime('%Y-%m')) 
df2.index.map(lambda x: x.strftime('%Y-%m')) 

但我不知道如何結合所有這些以達到預期效果?

非常感謝

回答

4

要合併上的信息是沒有明確隨處定義。當我們合併而不破壞它時,在索引中保留日期並不是一件好事。所以,我們將索引移到適當的數據框上,並創建兩個新的列進行合併。即,yearmonth。我將這部分封裝在一個函數中,以便更好地看到發生了什麼。

def f(df): 
    df = df.reset_index() 
    return df.assign(year=df.dat.dt.year, month=df.dat.dt.month) 

df = f(df1).merge(f(df2), on=['year', 'month'], suffixes=['', '_']) 

df.set_index('dat')[['x', 'y']] 

      x y 
dat    
2016-01-01 1 10 
2016-01-02 2 10 
2016-01-03 3 10 
2017-01-01 4 11 
2017-01-02 5 11 
2017-01-03 6 11 

這是使用pd.Index.mapto_period不同的概念。從df2創建一個字典映射,將年/月期對象轉換爲列y中的對應值。然後使用mapdf1.index中的期限日期映射到正確的y值。

m = dict(zip(df2.index.to_period('M'), df2.y)) 
df1.assign(y=df1.index.to_period('M').map(m.get)) 

      x y 
dat    
2016-01-01 1 10 
2016-01-02 2 10 
2016-01-03 3 10 
2017-01-01 4 11 
2017-01-02 5 11 
2017-01-03 6 11 

設置

dates1 = ['2016-01-01', '2016-01-02', '2016-01-03', 
      '2017-01-01', '2017-01-02', '2017-01-03'] 
df1 = pd.DataFrame({'x': range(1, 7)}, pd.DatetimeIndex(dates1, name='dat')) 

dates2 = ['2016-01-01', '2017-01-01'] 
df2 = pd.DataFrame({'y': [10, 11]}, pd.DatetimeIndex(dates2, name='dat')) 
+0

太好了,謝謝您的解釋! – olyashevska

3

你可以在yearmonth使用mergeassign從DateTimeIndex:

df3 = (df1.assign(year=df1.index.year, month=df1.index.month) 
     .merge(df2.assign(year=df2.index.year, month=df2.index.month), on =['year','month'],right_index=True) 
     .drop(['year','month'],axis=1)) 

輸出:

  x y 
dat    
2016-01-01 1 10 
2016-01-02 2 10 
2016-01-03 3 10 
2017-01-01 4 11 
2017-01-02 5 11 
2017-01-03 6 11 
相關問題