2016-09-30 71 views
2

我在pandas(v。0.18.0)似乎在DataFramevalues屬性上執行某些「幕後」轉換時遇到了一些困難。 我有一個數據集,看起來像下面這樣:熊貓DataFrame.values轉換錯誤或功能?

data = [(1473897600000000, 9.9166, 1.8621, 15), 
     (1473897660000000, 19.9166, 3.8621, 20), 
     (1473897720000000, 29.9166, 5.8621, 25), 
     (1473897780000000, 39.9166, 7.8621, 30)] 

每個元組的第一個元素代表了微秒的POSIX UTC時間戳。

dtype = [('timestamp', np.dtype('int64')), 
     ('a', np.dtype('float32')), 
     ('b', np.dtype('float32')), 
     ('c', np.dtype('uint8'))] 

我如用下面的代碼轉換這對一個DataFrame:每個元件的(name, dtype)由以下記錄陣列給出

data_array = np.array(data, dtype=dtype) 
df = pd.DataFrame.from_records(data_array) 

但是,下面的代碼給出一些奇怪的結果(至少對我來說):

ts_orig = np.array([x[0] for x in data], dtype=float) 
ts_column = df['timestamp'].values.astype(float) 
ts_values = df.values[:, 0] 
ts_diff = ts_values - ts_column 

print(np.column_stack((ts_orig, ts_column, ts_values, ts_diff))) 

# OUTPUT 
#  ts_orig   ts_column   ts_values  ts_diff 
[[ 1.47389760e+15 1.47389760e+15 1.47389762e+15 1.87351040e+07] 
[ 1.47389766e+15 1.47389766e+15 1.47389762e+15 -4.12648960e+07] 
[ 1.47389772e+15 1.47389772e+15 1.47389775e+15 3.29528320e+07] 
[ 1.47389778e+15 1.47389778e+15 1.47389775e+15 -2.70471680e+07]] 

看起來很清楚,將時間戳值轉換爲相同的浮點值val沒有問題直接(第1和2列)。準確的值仍然保留在DataFrame中,但是當整個DataFrame通過DataFrame.values屬性(第3列)轉換爲數組時,碰巧會擾亂時間戳值並將它們瘋狂拋出。

爲什麼會發生這種情況,我該如何預防它?

回答

1

冒着聽起來很愚蠢的風險,我會回答我自己的問題,應該先挖掘更深一層。該問題的根源是轉換到最小公分母類型,從DataFrame.values docmentation引述:

的D型細胞將是較低的公分母D型細胞(隱式向上轉型);也就是說,如果dtypes(即使是數字類型)是混合的,那麼可以選擇容納所有類型的dtypes。如果不處理塊,請小心使用

在這種情況下,所選的最適合的類型是float32,因此所有值均轉換爲該值。這可以存儲int64時間戳的值,但由於float32類型的數字精度問題,時間戳記值會捕捉到最接近的float32值。如果您將原始數據中的dtype值之一更改爲float64,則問題會靜默消失。

雖然這是後續問題。給定一個具有64位整數類型和浮點類型的混合數據集,最好的方法不是選擇最寬的類型(64位),因此不會丟失精度。

+2

在提取numpy數組之前轉換爲'float64':'df.astype(np.float64).values [:,0]' –