2015-05-05 72 views
3

我有一個Pandas數據幀,其中包含兩組日期,DatetimeIndex用於索引,而date2列包含datetime對象,一個值和一個id。對於某些id,我缺少date2等於索引的值,在這種情況下,我想用前一個DatetimeIndex和id的值填充行/值。 date1代表當前時間點,date2代表最後一個日期。每個df[df.id == id]可以被視爲自己的數據幀,但數據存儲在一個巨型數據幀500k行中。熊貓回填基於日期時間索引和列的值

實例:假設

  date2  id value 
index 
2006-01-24 2006-01-26 3 3  
2006-01-25 2006-01-26 1 1 
2006-01-25 2006-01-26 2 2 
2006-01-26 2006-01-26 2 2.1 
2006-01-27 2006-02-26 4 4 

在這個例子中,進行了缺少index == date2一行ID 1,ID 2和用於ID3。我想用與它的id相對應的前一個索引值來回填每個缺失的行。

我想回:

  date2  id value 
index 
2006-01-24 2006-01-26 3 3    
2006-01-25 2006-01-26 1 1 
2006-01-25 2006-01-26 2 2 
2006-01-26 2006-01-26 1 1 #<---- row added 
2006-01-26 2006-01-26 2 2.1 
2006-01-26 2006-01-26 3 3 #<---- row added 
2006-01-27 2006-02-26 4 4 
2006-02-26 2006-02-26 4 4 #<---- row added 
+0

你能解釋一下你添加新行的邏輯嗎? – fixxxer

回答

1

我稍微不願意回答B/C似乎@chrisb可能成功地回答了原來的問題,後來改變了。然而,克里斯在幾天內沒有更新答案,這個答案確實採取了不同的方法,所以我要+1克里斯的答案並添加這個答案。

首先,只需使用'index'='date2'創建一個新的數據框。這將是附加到現有的數據框的基礎上(注意,「索引」是這裏的列,而不是索引):

df2 = df[ df['index'] != df['date2'] ] 
df2['index'] = df2['date2'] 
df2['value'] = np.nan 

     index  date2 id value 
0 2006-01-26 2006-01-26 3 NaN 
1 2006-01-26 2006-01-26 1 NaN 
2 2006-01-26 2006-01-26 2 NaN 
4 2006-02-26 2006-02-26 4 NaN 

現在,只是追加所有這些,但下降的那些我們不需要(如果我們已經有'index'='date2'的現有行,至於id = 2這裏):

df3 = df.append(df2) 
df3 = df3.drop_duplicates(['index','date2','id']) 
df3 = df3.reset_index(drop=True).sort(['id','index','date2']) 
df3['value'] = df3.value.fillna(method='ffill') 

     index  date2 id value 
1 2006-01-25 2006-01-26 1 1.0 
6 2006-01-26 2006-01-26 1 1.0 
2 2006-01-25 2006-01-26 2 2.0 
3 2006-01-26 2006-01-26 2 2.1 
0 2006-01-24 2006-01-26 3 3.0 
5 2006-01-26 2006-01-26 3 3.0 
4 2006-01-27 2006-02-26 4 4.0 
7 2006-02-26 2006-02-26 4 4.0 
2

這是不是很乾淨,但它是一個可能的解決方案。首先,我提出的索引到柱中,date1

In [228]: df 
Out[228]: 
     date1  date2 id value 
0 2006-01-24 2006-01-26 3 3.0 
1 2006-01-25 2006-01-26 1 1.0 
2 2006-01-25 2006-01-26 2 2.0 
3 2006-01-26 2006-01-26 2 2.1 

然後我由每對日期的分組,將IDS那些對那個匹配。這涉及將DataFrame分成子幀列表並使用concat來一起粘合。

In [229]: dfs = [] 
    ...: for (date1, date2), df_gb in df.groupby(['date1','date2']): 
    ...:  if date1 == date2: 
    ...:   to_add = list(set([1,2,3]) - set(df_gb['id'])) 
    ...:   df_gb = df_gb.append(pd.DataFrame({'id': to_add, 'date1': date1, 'date2': date2, 'value': np.nan}), ignore_index=True) 
    ...:  dfs.append(df_gb) 

In [231]: df = pd.concat(dfs, ignore_index=True) 

In [232]: df 
Out[232]: 
     date1  date2 id value 
0 2006-01-24 2006-01-26 3 3.0 
1 2006-01-25 2006-01-26 1 1.0 
2 2006-01-25 2006-01-26 2 2.0 
3 2006-01-26 2006-01-26 2 2.1 
4 2006-01-26 2006-01-26 1 NaN 
5 2006-01-26 2006-01-26 3 NaN 

最後,我排序並填寫缺失的值。

In [233]: df = df.sort(['id', 'date1', 'date2']) 

In [234]: df = df.fillna(method='ffill') 

In [236]: df.sort(['date1', 'date2']) 
Out[236]: 
     date1  date2 id value 
0 2006-01-24 2006-01-26 3 3.0 
1 2006-01-25 2006-01-26 1 1.0 
2 2006-01-25 2006-01-26 2 2.0 
4 2006-01-26 2006-01-26 1 1.0 
3 2006-01-26 2006-01-26 2 2.1 
5 2006-01-26 2006-01-26 3 3.0 
+0

Arg!謝謝,但剛剛在這發現了一個邊緣案例,我會更新我的問題,這是密切的你。 – pyCthon

+0

本質上,如果我有整個集合的多個date2值,並且id 1只有一個date2值,我現在爲id 1的每個date2獲取一個值。 – pyCthon