我遇到的问题是,使用ndarray.view(np.dtype)
从经典ndarray获取结构化数组似乎错误地计算了float
到int
转换。
示例更好地说明:
In [12]: B
Out[12]:
array([[ 1.00000000e+00, 1.00000000e+00, 0.00000000e+00,
0.00000000e+00, 4.43600000e+01, 0.00000000e+00],
[ 1.00000000e+00, 2.00000000e+00, 7.10000000e+00,
1.10000000e+00, 4.43600000e+01, 1.32110000e+02],
[ 1.00000000e+00, 3.00000000e+00, 9.70000000e+00,
2.10000000e+00, 4.43600000e+01, 2.04660000e+02],
...,
[ 1.28900000e+03, 1.28700000e+03, 0.00000000e+00,
9.99999000e+05, 4.75600000e+01, 3.55374000e+03],
[ 1.28900000e+03, 1.28800000e+03, 1.29000000e+01,
5.40000000e+00, 4.19200000e+01, 2.08400000e+02],
[ 1.28900000e+03, 1.28900000e+03, 0.00000000e+00,
0.00000000e+00, 4.19200000e+01, 0.00000000e+00]])
In [14]: B.view(A.dtype)
Out[14]:
array([(4607182418800017408, 4607182418800017408, 0.0, 0.0, 44.36, 0.0),
(4607182418800017408, 4611686018427387904, 7.1, 1.1, 44.36, 132.11),
(4607182418800017408, 4613937818241073152, 9.7, 2.1, 44.36, 204.66),
...,
(4653383897399164928, 4653375101306142720, 0.0, 999999.0, 47.56, 3553.74),
(4653383897399164928, 4653379499352653824, 12.9, 5.4, 41.92, 208.4),
(4653383897399164928, 4653383897399164928, 0.0, 0.0, 41.92, 0.0)],
dtype=[('i', '<i8'), ('j', '<i8'), ('tnvtc', '<f8'), ('tvtc', '<f8'), ('tf', '<f8'), ('tvps', '<f8')])
'i'和'j'列是真正的整数:
这里有两个我已经完成的检查,问题似乎来自ndarray.view(np.int)
In [21]: B[:,:2]
Out[21]:
array([[ 1.00000000e+00, 1.00000000e+00],
[ 1.00000000e+00, 2.00000000e+00],
[ 1.00000000e+00, 3.00000000e+00],
...,
[ 1.28900000e+03, 1.28700000e+03],
[ 1.28900000e+03, 1.28800000e+03],
[ 1.28900000e+03, 1.28900000e+03]])
In [22]: B[:,:2].view(np.int)
Out[22]:
array([[4607182418800017408, 4607182418800017408],
[4607182418800017408, 4611686018427387904],
[4607182418800017408, 4613937818241073152],
...,
[4653383897399164928, 4653375101306142720],
[4653383897399164928, 4653379499352653824],
[4653383897399164928, 4653383897399164928]])
In [23]: B[:,:2].astype(np.int)
Out[23]:
array([[ 1, 1],
[ 1, 2],
[ 1, 3],
...,
[1289, 1287],
[1289, 1288],
[1289, 1289]])
我做错了什么?由于numpy分配内存,我不能改变类型吗?还有另一种方法可以做到这一点(fromarrays,指责shape mismatch
?
答案 0 :(得分:1)
实际上,from_arrays有效,但它没有解释这种奇怪的比赛。
以下是我找到的解决方案:
np.core.records.fromarrays(B.T, dtype=A.dtype)
答案 1 :(得分:1)
这是执行somearray.view(new_dtype)
和调用astype
之间的区别。
你所看到的正是预期的行为,而且是非常慎重的,但是当你第一次碰到它时就会起义。
具有不同dtype的视图将数组的底层内存缓冲区解释为给定的dtype。没有制作副本。它非常强大,但你必须了解你在做什么。
要记住的一个关键事项是,调用view
永远不会改变底层内存缓冲区,就像numpy所看到的那样(例如dtype,shape,strides)。因此,view
故意避免将数据更改为新类型,而只是将“旧位”解释为新的dtype。
例如:
In [1]: import numpy as np
In [2]: x = np.arange(10)
In [3]: x
Out[3]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [4]: x.dtype
Out[4]: dtype('int64')
In [5]: x.view(np.int32)
Out[5]: array([0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0],
dtype=int32)
In [6]: x.view(np.float64)
Out[6]:
array([ 0.00000000e+000, 4.94065646e-324, 9.88131292e-324,
1.48219694e-323, 1.97626258e-323, 2.47032823e-323,
2.96439388e-323, 3.45845952e-323, 3.95252517e-323,
4.44659081e-323])
如果您想使用新的dtype复制数组,请改用astype
:
In [7]: x
Out[7]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [8]: x.astype(np.int32)
Out[8]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
In [9]: x.astype(float)
Out[9]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
但是,对结构化数组使用astype
可能会让您感到惊讶。结构化数组将输入的每个元素视为类似C的结构。因此,如果你致电astype
,你会遇到几个惊喜。
基本上,您希望列具有不同的dtype。在这种情况下,请不要将它们放在同一个数组中。 Numpy阵列预计是同质的。结构化数组在某些情况下很方便,但如果您正在寻找处理单独数据列的内容,它们可能不是您想要的。只需将每列用作自己的数组。
更好的是,如果你使用表格数据,你可能会发现它比直接使用numpy数组更容易使用pandas
。 pandas
面向表格数据(其中列预计具有不同的类型),而numpy则面向同质数组。
答案 2 :(得分:0)
在类似情况下对我有用的唯一解决方案:
var newData = // your data as DataTable Format;
// Get Current Scroll position
var scrollingRowIndex = MyDataGridView.FirstDisplayedScrollingRowIndex;
// Get Current Row
var currentRow = MyDataGridView.CurrentCell != null
? MyDataGridView.CurrentCell.RowIndex
: -1;
DataTable bindedData;
var currentDataSource = MyDataGridView.DataSource as DataTable;
if (currentDataSource != null)
{
currentDataSource.Merge(newData);
bindedData = currentDataSource;
}
else
{
bindedData = newData;
}
MyDataGridView.DataSource = bindedData;
MyDataGridView.Update();
// set Current Scroll position
if (scrollingRowIndex > -1)
MyDataGridView.FirstDisplayedScrollingRowIndex = scrollingRowIndex;
// set Current Row
if (currentRow > -1)
MyDataGridView.Rows[currentRow].Selected = true;