2013-06-27 18 views
3

你能解釋這種奇怪的行爲嗎?使用帶有浮點數的pandas reindex:插值

df=pd.DataFrame({'year':[1986,1987,1988],'bomb':arange(3)}).set_index('year') 

In [9]: df.reindex(arange(1986,1988.125,.125)) 
Out[9]: 
      bomb 
1986.000  0 
1986.125 NaN 
1986.250 NaN 
1986.375 NaN 
1986.500 NaN 
1986.625 NaN 
1986.750 NaN 
1986.875 NaN 
1987.000  1 
1987.125 NaN 
1987.250 NaN 
1987.375 NaN 
1987.500 NaN 
1987.625 NaN 
1987.750 NaN 
1987.875 NaN 
1988.000  2 

In [10]: df.reindex(arange(1986,1988.1,.1)) 
Out[10]: 
     bomb 
1986.0  0 
1986.1 NaN 
1986.2 NaN 
1986.3 NaN 
1986.4 NaN 
1986.5 NaN 
1986.6 NaN 
1986.7 NaN 
1986.8 NaN 
1986.9 NaN 
1987.0 NaN 
1987.1 NaN 
1987.2 NaN 
1987.3 NaN 
1987.4 NaN 
1987.5 NaN 
1987.6 NaN 
1987.7 NaN 
1987.8 NaN 
1987.9 NaN 
1988.0 NaN 

當增量以外的任何其他.125,我發現,新的索引值不會「發現」具有匹配值的舊行。即有一個精確的問題沒有被克服。即使我在嘗試插入之前強制索引爲浮點數,情況也是如此。發生了什麼事情和/或什麼是正確的做法? 我已經能夠通過使用

reindex( np.array(map(round,arange(1985,2010+dt,dt)*10))/10.0) 

順便說得到它以0.1增量工作,我這樣做是爲線性內插了一些列的第一個步驟(例如「炸彈」是其中之一)。如果有更好的方法來做到這一點,我會很樂意設置。

+0

看起來像你真正想要一個datelike指數做這樣的事情,還是你真的出於某種原因想要一個浮動指標?你最終想要什麼? – Jeff

+0

是的,我想它是有約會的,但除了一年的小數點以外,我真的不需要特別的/聰明的功能。最終的輸出?是這樣的:http://www.youtube.com/watch?v=1BGzzykW_QM&feature=youtu.be即我有數據好幾年了,我想插入列值到一個(更精細)的網格,以順利進行動畫。 – CPBL

回答

0

你正在得到你所要求的。 reindex方法只會嘗試將數據轉換爲您提供的新索引。正如評論中提到的,您可能正在索引中尋找日期。我猜你期待重新索引方法來做到這一點,但(插值):

df2 =df.reindex(arange(1986,1988.125,.125)) 
pd.Series.interpolate(df2['bomb']) 

1986.000 0.000 
1986.125 0.125 
1986.250 0.250 
1986.375 0.375 
1986.500 0.500 
1986.625 0.625 
1986.750 0.750 
1986.875 0.875 
1987.000 1.000 
1987.125 1.125 
1987.250 1.250 
1987.375 1.375 
1987.500 1.500 
1987.625 1.625 
1987.750 1.750 
1987.875 1.875 
1988.000 2.000 
Name: bomb 

你使用第二個例子是不一致是由於浮點精度的可能。步進0.125等於1/8,這可以精確地以二進制完成。步進0.1不能直接映射到二進制,所以1987可能只是一小部分。

1987.0 == 1987.0000000001 
False 
+1

謝謝。不,我並不希望reindex做內插。正如我所說,這是插值的第一步/設置。 「1/8完全可以用二進制完成」是我缺少的主要洞察力。但我仍然沒有看到我得到了我所要求的。特別是當示例失敗時,即使索引是浮點數。 – CPBL

+1

請看這裏:http://pandas.pydata.org/pandas-docs/dev/indexing.html#fallback-indexing,浮動指數幾乎總是一個壞主意;既然你不可能完全匹配所有漂浮物你有問題;要麼使用像索引一樣的日期時間int索引,要麼使用多個列甚至字符串索引 – Jeff

0

我認爲你最好使用PeriodIndex

In [39]: df=pd.DataFrame({'bomb':np.arange(3)}) 

In [40]: df 
Out[40]: 
    bomb 
0  0 
1  1 
2  2 

In [41]: df.index = pd.period_range('1986','1988',freq='Y').asfreq('M') 

In [42]: df 
Out[42]: 
     bomb 
1986-12  0 
1987-12  1 
1988-12  2 

In [43]: df = df.reindex(pd.period_range('1986','1988',freq='M')) 

In [44]: df 
Out[44]: 
     bomb 
1986-01 NaN 
1986-02 NaN 
1986-03 NaN 
1986-04 NaN 
1986-05 NaN 
1986-06 NaN 
1986-07 NaN 
1986-08 NaN 
1986-09 NaN 
1986-10 NaN 
1986-11 NaN 
1986-12  0 
1987-01 NaN 
1987-02 NaN 
1987-03 NaN 
1987-04 NaN 
1987-05 NaN 
1987-06 NaN 
1987-07 NaN 
1987-08 NaN 
1987-09 NaN 
1987-10 NaN 
1987-11 NaN 
1987-12  1 
1988-01 NaN 
In [45]: df.iloc[0,0] = -1 

In [46]: df['interp'] = df['bomb'].interpolate() 

In [47]: df 
Out[47]: 
     bomb interp 
1986-01 -1 -1.000000 
1986-02 NaN -0.909091 
1986-03 NaN -0.818182 
1986-04 NaN -0.727273 
1986-05 NaN -0.636364 
1986-06 NaN -0.545455 
1986-07 NaN -0.454545 
1986-08 NaN -0.363636 
1986-09 NaN -0.272727 
1986-10 NaN -0.181818 
1986-11 NaN -0.090909 
1986-12  0 0.000000 
1987-01 NaN 0.083333 
1987-02 NaN 0.166667 
1987-03 NaN 0.250000 
1987-04 NaN 0.333333 
1987-05 NaN 0.416667 
1987-06 NaN 0.500000 
1987-07 NaN 0.583333 
1987-08 NaN 0.666667 
1987-09 NaN 0.750000 
1987-10 NaN 0.833333 
1987-11 NaN 0.916667 
1987-12  1 1.000000 
1988-01 NaN 1.000000