我对某些“幕后”转换感到困难,pandas
(v。0.18.0)似乎对values
的{{1}}属性执行了转换。
我有一个类似于以下内容的数据集:
DataFrame
每个元组的第一个元素表示POSIX UTC时间戳,以微秒为单位。每个元素的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)]
由以下记录数组给出:
(name, dtype)
我正在使用以下代码将其转换为dtype = [('timestamp', np.dtype('int64')),
('a', np.dtype('float32')),
('b', np.dtype('float32')),
('c', np.dtype('uint8'))]
:
DataFrame
但是,以下代码给出了一些奇怪的结果(至少对我来说):
data_array = np.array(data, dtype=dtype)
df = pd.DataFrame.from_records(data_array)
似乎很清楚,将时间戳值直接转换为相同的浮点值(第1列和第2列)没有问题。准确的值仍然保留在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]]
中,但是当整个DataFrame
通过DataFrame
属性(第3列)转换为数组时,会发生一些事情来加扰时间戳值并将它们大量抛出关闭。
为什么会发生这种情况,我该如何预防?
答案 0 :(得分:1)
冒着听起来很愚蠢的风险,我会回答我自己的问题,应该先挖一点。问题的根源是转换为最小公分母类型,引用DataFrame.values文档:
dtype将是一个较低的共同分母dtype(隐式向上转换);也就是说,如果dtypes(甚至是数字类型)混合在一起,那么将选择容纳所有dtypes的那个。如果您不处理块
,请小心使用
在这种情况下,选择的最容纳的类型是float32
,因此所有值都将转换为该值。这可以存储int64
时间戳的值,但由于float32
类型的数字精度问题,时间戳值会捕捉到最接近的float32
值。如果您将原始数据中的dtype
值之一更改为float64
,则问题会以无声方式消失。
这是一个后续问题。给定具有64位整数类型和浮点类型的混合数据集,最好的选择是选择最宽类型(64位),以便不丢失精度?