numpy - Change/Specify 掩码数组列的数据类型
numpy - Change/Specify dtypes of masked array columns
我有一个包含大量数据的 csv 文件,我想将其作为掩码数组读取。我使用以下方法完成了此操作:
data=np.recfromcsv(filename,case_sensitive=True,usemask=True)
效果很好。但是,我的问题是数据要么是字符串、整数,要么是浮点数。我现在想做的是将所有整数转换为浮点数,即转换所有“1"s into "1.0”等,同时保留其他所有内容。
此外,我正在寻找通用解决方案。因此,由于 csv 文件(包括列数)发生了变化,因此仅手动指定所需的类型是行不通的。
我试过 astype 但是因为数组也有不起作用的字符串条目,还是我遗漏了什么?
谢谢。
我没有使用过 recfromcsv
,但查看它的代码我发现它使用了 np.genfromtxt
,然后是屏蔽记录构造。
我建议提供一个小示例 csv
文本(大约 3 行),并显示结果 data
。我们需要特别查看 dtype
。
从 genfromtxt
开始可能也很有用,暂时跳过屏蔽数组的内容。我认为这不是在结构化数组中转换数据类型的关键所在。
无论如何,我们需要更具体的东西来探索。
您无法就地更改结构化字段的 dtype
。您必须使用新的 dtype 创建一个新数组,并将值从旧的复制到新的。
import numpy.lib.recfunctions as rf
有一些函数可以帮助改变结构化数组。
===========
我怀疑在调用 genfromtxt
时拼出 dtypes
比更改现有数组中的数据类型更简单。
您可以尝试使用 dtype=None
和有限行数进行一次读取以获得列数和基数 dtype
。然后编辑它,根据需要用浮点数代替整数。现在用新的 dtype 阅读全部内容。如果您需要有关如何编辑数据类型的想法,请查看 recfunctions
代码。
例如:
In [504]: txt=b"""a, 1, 2, 4\nb, 6, 9, 10\nc, 4, 4, 3"""
In [506]: arr = np.genfromtxt(txt.splitlines(), dtype=None, delimiter=',')
In [507]: arr
Out[507]:
array([(b'a', 1, 2, 4), (b'b', 6, 9, 10), (b'c', 4, 4, 3)],
dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])
In [508]: arr.dtype.descr
Out[508]: [('f0', '|S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')]
一个粗糙的 dtype 编辑器:
def foo(tup):
name, dtype=tup
dtype = dtype.replace('S','U')
dtype = dtype.replace('i','f')
return name, dtype
并将其应用于默认数据类型:
In [511]: dt = [foo(tup) for tup in arr.dtype.descr]
In [512]: dt
Out[512]: [('f0', '|U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')]
In [513]: arr = np.genfromtxt(txt.splitlines(), dtype=dt, delimiter=',')
In [514]: arr
Out[514]:
array([('a', 1.0, 2.0, 4.0), ('b', 6.0, 9.0, 10.0), ('c', 4.0, 4.0, 3.0)],
dtype=[('f0', '<U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')])
In [522]: arr = np.recfromcsv(txt.splitlines(), dtype=dt, delimiter=',',case_sensitive=True,usemask=True,names=None)
In [523]: arr
Out[523]:
masked_records(
f0 : ['a' 'b' 'c']
f1 : [1.0 6.0 4.0]
f2 : [2.0 9.0 4.0]
f3 : [4.0 10.0 3.0]
fill_value : ('N', 1.0000000200408773e+20, 1.0000000200408773e+20, 1.0000000200408773e+20)
)
=====================
astype
如果目标 dtype 匹配则有效。例如,如果我用 dtype=None 读取 txt
,然后使用派生的 dt
,它有效:
In [530]: arr = np.genfromtxt(txt.splitlines(), delimiter=',',dtype=None)
In [531]: arr
Out[531]:
array([(b'a', 1, 2, 4), (b'b', 6, 9, 10), (b'c', 4, 4, 3)],
dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])
In [532]: arr.astype(dt)
Out[532]:
array([('a', 1.0, 2.0, 4.0), ('b', 6.0, 9.0, 10.0), ('c', 4.0, 4.0, 3.0)],
dtype=[('f0', '<U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')])
与 arr.astype('U3,int,float,int')
相同,它也有 4 个兼容字段。
我有一个包含大量数据的 csv 文件,我想将其作为掩码数组读取。我使用以下方法完成了此操作:
data=np.recfromcsv(filename,case_sensitive=True,usemask=True)
效果很好。但是,我的问题是数据要么是字符串、整数,要么是浮点数。我现在想做的是将所有整数转换为浮点数,即转换所有“1"s into "1.0”等,同时保留其他所有内容。
此外,我正在寻找通用解决方案。因此,由于 csv 文件(包括列数)发生了变化,因此仅手动指定所需的类型是行不通的。
我试过 astype 但是因为数组也有不起作用的字符串条目,还是我遗漏了什么?
谢谢。
我没有使用过 recfromcsv
,但查看它的代码我发现它使用了 np.genfromtxt
,然后是屏蔽记录构造。
我建议提供一个小示例 csv
文本(大约 3 行),并显示结果 data
。我们需要特别查看 dtype
。
从 genfromtxt
开始可能也很有用,暂时跳过屏蔽数组的内容。我认为这不是在结构化数组中转换数据类型的关键所在。
无论如何,我们需要更具体的东西来探索。
您无法就地更改结构化字段的 dtype
。您必须使用新的 dtype 创建一个新数组,并将值从旧的复制到新的。
import numpy.lib.recfunctions as rf
有一些函数可以帮助改变结构化数组。
===========
我怀疑在调用 genfromtxt
时拼出 dtypes
比更改现有数组中的数据类型更简单。
您可以尝试使用 dtype=None
和有限行数进行一次读取以获得列数和基数 dtype
。然后编辑它,根据需要用浮点数代替整数。现在用新的 dtype 阅读全部内容。如果您需要有关如何编辑数据类型的想法,请查看 recfunctions
代码。
例如:
In [504]: txt=b"""a, 1, 2, 4\nb, 6, 9, 10\nc, 4, 4, 3"""
In [506]: arr = np.genfromtxt(txt.splitlines(), dtype=None, delimiter=',')
In [507]: arr
Out[507]:
array([(b'a', 1, 2, 4), (b'b', 6, 9, 10), (b'c', 4, 4, 3)],
dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])
In [508]: arr.dtype.descr
Out[508]: [('f0', '|S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')]
一个粗糙的 dtype 编辑器:
def foo(tup):
name, dtype=tup
dtype = dtype.replace('S','U')
dtype = dtype.replace('i','f')
return name, dtype
并将其应用于默认数据类型:
In [511]: dt = [foo(tup) for tup in arr.dtype.descr]
In [512]: dt
Out[512]: [('f0', '|U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')]
In [513]: arr = np.genfromtxt(txt.splitlines(), dtype=dt, delimiter=',')
In [514]: arr
Out[514]:
array([('a', 1.0, 2.0, 4.0), ('b', 6.0, 9.0, 10.0), ('c', 4.0, 4.0, 3.0)],
dtype=[('f0', '<U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')])
In [522]: arr = np.recfromcsv(txt.splitlines(), dtype=dt, delimiter=',',case_sensitive=True,usemask=True,names=None)
In [523]: arr
Out[523]:
masked_records(
f0 : ['a' 'b' 'c']
f1 : [1.0 6.0 4.0]
f2 : [2.0 9.0 4.0]
f3 : [4.0 10.0 3.0]
fill_value : ('N', 1.0000000200408773e+20, 1.0000000200408773e+20, 1.0000000200408773e+20)
)
=====================
astype
如果目标 dtype 匹配则有效。例如,如果我用 dtype=None 读取 txt
,然后使用派生的 dt
,它有效:
In [530]: arr = np.genfromtxt(txt.splitlines(), delimiter=',',dtype=None)
In [531]: arr
Out[531]:
array([(b'a', 1, 2, 4), (b'b', 6, 9, 10), (b'c', 4, 4, 3)],
dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')])
In [532]: arr.astype(dt)
Out[532]:
array([('a', 1.0, 2.0, 4.0), ('b', 6.0, 9.0, 10.0), ('c', 4.0, 4.0, 3.0)],
dtype=[('f0', '<U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')])
与 arr.astype('U3,int,float,int')
相同,它也有 4 个兼容字段。