python - 用于记录的 numpy astype 的奇怪行为
问题描述
我正在使用 numpy 的.astype()
方法来转换数据类型,但是,它给出了奇怪的结果,假设以下代码:
import pandas as pd
import numpy as np
import sys
df = pd.DataFrame([[0.1, 2, 'a']], columns=["a1", "a2", "str"])
arr = df.to_records(index=False)
dtype1 = [('a1', np.float32), ('a2', np.int32), ('str', '|S2')]
dtype2 = [('a2', np.int32), ('a1', np.float32), ('str', '|S2')]
arr1 = arr.astype(dtype1)
arr2 = arr.astype(dtype2)
print(arr1)
print(arr2)
print(arr)
print(sys.version)
print(np.__version__)
print(pd.__version__)
我已经在不同的 python 版本上对其进行了测试,并给了我不同的结果。较新的版本给了我意想不到的结果:
[(0.1, 2, b'a')]
[(0, 2., b'a')]
[(0.1, 2, 'a')]
3.6.5 |Anaconda custom (64-bit)| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)]
1.15.0
0.23.4
虽然旧版本给出了正确的结果:
[(0.10000000149011612, 2, 'a') (0.10000000149011612, 2, 'b')]
[(2, 0.10000000149011612, 'a') (2, 0.10000000149011612, 'b')]
[(0.1, 2L, 'a') (0.1, 2L, 'b')]
2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)]
1.11.1
0.20.3
有人可以告诉我发生了什么吗?
解决方案
https://docs.scipy.org/doc/numpy/user/basics.rec.html#assignment-from-other-structured-arrays
表示来自其他结构化数组的分配是按位置,而不是按字段名称。我认为这适用于astype
. 如果是这样,则意味着您无法使用astype
.
一次访问多个字段在最近的版本中发生了变化,并且可能会发生更多变化。部分原因是这种访问应该是副本还是视图。
recfunctions
具有添加、删除或合并字段的代码。一个常见的策略是使用新的 dtype 创建一个目标数组,并通过字段名称将值复制到它。这是迭代的,但由于通常数组的记录比字段多,因此时间损失不大,
在 1.14 版本中,我可以这样做:
In [152]: dt1 = np.dtype([('a',float),('b',int), ('c','U3')])
In [153]: dt2 = np.dtype([('b',int),('a',float), ('c','S3')])
In [154]: arr1 = np.array([(1,2,'a'),(3,4,'b'),(5,6,'c')], dt1)
In [155]: arr1
Out[155]:
array([(1., 2, 'a'), (3., 4, 'b'), (5., 6, 'c')],
dtype=[('a', '<f8'), ('b', '<i8'), ('c', '<U3')])
简单地使用astype
不会重新排序字段:
In [156]: arr1.astype(dt2)
Out[156]:
array([(1, 2., b'a'), (3, 4., b'b'), (5, 6., b'c')],
dtype=[('b', '<i8'), ('a', '<f8'), ('c', 'S3')])
但多字段索引确实:
In [157]: arr1[['b','a','c']]
Out[157]:
array([(2, 1., 'a'), (4, 3., 'b'), (6, 5., 'c')],
dtype=[('b', '<i8'), ('a', '<f8'), ('c', '<U3')])
现在dt2
astype 是正确的:
In [158]: arr2 = arr1[['b','a','c']].astype(dt2)
In [159]: arr2
Out[159]:
array([(2, 1., b'a'), (4, 3., b'b'), (6, 5., b'c')],
dtype=[('b', '<i8'), ('a', '<f8'), ('c', 'S3')])
In [160]: arr1['a']
Out[160]: array([1., 3., 5.])
In [161]: arr2['a']
Out[161]: array([1., 3., 5.])
这是 1.14;您使用的是 1.15,并且文档提到了 1.16 中的差异。所以这是一个移动的目标。
的astype
行为与分配给“空白”数组的行为相同:
In [162]: arr2 = np.zeros(arr1.shape, dt2)
In [163]: arr2
Out[163]:
array([(0, 0., b''), (0, 0., b''), (0, 0., b'')],
dtype=[('b', '<i8'), ('a', '<f8'), ('c', 'S3')])
In [164]: arr2[:] = arr1
In [165]: arr2
Out[165]:
array([(1, 2., b'a'), (3, 4., b'b'), (5, 6., b'c')],
dtype=[('b', '<i8'), ('a', '<f8'), ('c', 'S3')])
In [166]: arr2[:] = arr1[['b','a','c']]
In [167]: arr2
Out[167]:
array([(2, 1., b'a'), (4, 3., b'b'), (6, 5., b'c')],
dtype=[('b', '<i8'), ('a', '<f8'), ('c', 'S3')])
推荐阅读
- reactjs - RN FlatList 不渲染项目(hooks + redux + thunk)
- javascript - 节点:fs.watch() 太快了
- r - 为什么 R 中的 textreuse packge 使 LSH 存储桶比原始 minhashes 大得多?
- sap-business-one-di-api - SAP Business One 集成框架浏览器卡在“正在加载”
- java - 在 Eclipse 中导出 java 项目时如何清除旧类?
- java - Android 通过点击按钮事件保存联系人
- binary - 代表5位数据的单词?
- python - 使用 Dijkstra 最小化成本?
- ios - SwiftUI - 我可以与提取的子视图共享功能吗?
- python - 如何将 'google.cloud.documentai.v1beta2.types.document.Document' 转换为 JSON?