1

我有一个 csv 文件,其中包含我想作为掩码数组读取的大量数据。我已经使用以下方法做到了:

data=np.recfromcsv(filename,case_sensitive=True,usemask=True)

效果很好。但是,我的问题是数据是字符串、整数或浮点数。我现在要做的是将所有整数转换为浮点数,即将所有“1”转换为“1.0”等,同时保留其他所有内容。

此外,我正在寻找一个通用的解决方案。因此,由于 csv 文件(包括列数)发生了变化,因此仅手动指定所需的类型是行不通的。

我试过astype但由于数组也有不起作用的字符串条目,还是我遗漏了什么?

谢谢。

4

1 回答 1

0

我没有使用过recfromcsv,但是查看它的代码,我看到它使用np.genfromtxt过,然后是一个蒙面记录构造。

我建议给出一个小的示例csv文本(3 行左右),并显示结果data。我们需要dtype特别看到。

genfromtxt从 开始,暂时跳过屏蔽数组的内容也可能很有用。我认为这不是在结构化数组中转换 dtype 的关键所在。

无论如何,我们需要更具体的东西来探索。

您不能dtype就地更改结构化字段的 。您必须使用新的 dtype 创建一个新数组,并将值从旧的复制到新的。

import numpy.lib.recfunctions as rf

有一些函数可以帮助改变结构化数组。

===========

我怀疑dtypes在调用时拼写genfromtxt比在现有数组中更改 dtype 更简单。

您可以尝试使用dtype=None有限的行数进行一次读取,以获取列数和 base dtype。然后编辑它,根据需要用浮点数替换整数。现在用新的 dtype 阅读全文。recfunctions如果您需要有关如何编辑 dtypes的想法,请查看代码。

例如:

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

并将其应用于默认 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 匹配,则有效。例如,如果我阅读txtwith dtype=None,然后使用 derived 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 个兼容的字段。

于 2017-01-05T19:32:27.433 回答