我使用numpy genfromtxt来读取CSV数据文件,然后将其堆叠成单个结构化的numpy数组。但是,我遇到了一些问题,因为在某些文件中,某些字段中缺少所有数据。因此,当我尝试堆叠数据时,我得到一个“TypeError:Incompatible type”,该字段包含所有缺失的数据。
有没有办法通过在genfromtxt中设置默认的missing_values dtype,或者在堆叠数组时以某种方式处理类型不匹配来处理这个问题?
注意,我不知道字段数据类型将提前是什么。
import numpy as np
import numpy.lib.recfunctions as RF
#=====================================================
#------------ file test0.csv ----------
# fld1, fld2, fld3, fld4, fld5
# aaa, 1, , 3.0, 4
# bbb, 2, , 4.1, 3
# ccc, 3, , 5.2, 2
# ddd, 4, , 6.3, 1
#
#------------ file test1.csv ----------
# fld1, fld2, fld3, fld4, fld5
# aaa, 1, 2.0, 3.0, 4
# bbb, 2, 2.1, 4.1, 3
# ccc, 3, 2.2, 5.2, 2
# ddd, 4, 2.3, 6.3, 1
#
#====================================================================
fn0 = r'C:\temp\test0.csv'
fn1 = r'C:\temp\test1.csv'
a0 = np.genfromtxt(fn0, dtype=None, delimiter=',', names=True)
a1 = np.genfromtxt(fn1, dtype=None, delimiter=',', names=True)
da = RF.stack_arrays((a0,a1))
答案 0 :(得分:0)
您的样本a2.dtype
是
dtype=[('fld1', 'S3'), ('fld2', '<i4'),
('fld3', '<f8'), ('fld4', '<f8'), ('fld5', '<i4')
但适用于a1
('fld3', '?')
,因为没有数据可以从中推断出类型。
如果我定义了一个dtype列表
dt=['S3',int,float,float,int]
a2 = np.genfromtxt(txt2, dtype=dt, delimiter=',', names=True)
a1 = np.genfromtxt(txt1, dtype=dt, delimiter=',', names=True)
然后数组有一个共同的dtype
,我可以连接(不需要RF
版本):
In [25]: np.concatenate([a1,a2],axis=0)
Out[25]:
array([(b'aaa', 1, nan, 3.0, 4), (b'bbb', 2, nan, 4.1, 3),
(b'ccc', 3, nan, 5.2, 2), (b'ddd', 4, nan, 6.3, 1),
(b'aaa', 1, 2.0, 3.0, 4), (b'bbb', 2, 2.1, 4.1, 3),
(b'ccc', 3, 2.2, 5.2, 2), (b'ddd', 4, 2.3, 6.3, 1)],
dtype=[('fld1', 'S3'), ('fld2', '<i4'), ('fld3', '<f8'), ('fld4', '<f8'), ('fld5', '<i4')])
我没有看到像dt
这样明确的列表。我可以看到参数中没有任何内容,我可以说,例如,在使用dtype=None
时,未知列应为float
。
创建后,更改所选字段的dtype以使其兼容需要花费大量的精力。改名很容易。但是更改字段dtype很可能需要创建一个新的空数组并复制字段。
查看a1.itemsize
和a2.itemsize
。它们分别是20和27。
==========================
这是加载后更改dtype的示例。 a1n
和a2n
是使用dtype=None
创建的数组:
来自a1
的形状为空的数组,但来自a2
的dtype:
In [31]: a1nn = np.zeros(a1n.shape, dtype=a2n.dtype)
In [32]: for n in a1nn.dtype.names:
....: a1nn[n]=a1n[n] # copy fields by name
....:
In [33]: a1nn
Out[33]:
array([(b'aaa', 1, 0.0, 3.0, 4), (b'bbb', 2, 0.0, 4.1, 3),
(b'ccc', 3, 0.0, 5.2, 2), (b'ddd', 4, 0.0, 6.3, 1)],
dtype=[('fld1', 'S3'), ('fld2', '<i4'), ('fld3', '<f8'), ('fld4', '<f8'), ('fld5', '<i4')])
In [34]: np.concatenate([a1nn,a2n])
Out[34]:
array([(b'aaa', 1, 0.0, 3.0, 4), (b'bbb', 2, 0.0, 4.1, 3),
(b'ccc', 3, 0.0, 5.2, 2), (b'ddd', 4, 0.0, 6.3, 1),
(b'aaa', 1, 2.0, 3.0, 4), (b'bbb', 2, 2.1, 4.1, 3),
(b'ccc', 3, 2.2, 5.2, 2), (b'ddd', 4, 2.3, 6.3, 1)],
dtype=[('fld1', 'S3'), ('fld2', '<i4'), ('fld3', '<f8'), ('fld4', '<f8'), ('fld5', '<i4')])
genfromtxt
使用np.nan
填充了缺少的字段,但此路由使用了0
。
RF
有一个逐字段复制数组的函数,但是当dtype
嵌套时会递归复制。