我想知道当从给定(csv)文件中加载包含多列和字符串和数值的多列数据时,如何替换特定值。
在下面的示例中,假设您有许多地理位置,具有已知的纬度和经度,以及一组特定的属性(P1-P5)和一个类(仅包括问题的字符串部分)。有一些丢失的值已被genfromtxt正确替换(在这种情况下,丢失值是-999),此外,还有一些不正确的值(伪造或其他类型的标志),例如0.0。如何将0.0替换为-999?
数据:
Name,lat,long,P1,P2,P3,P4,P5,Class
id1,71.234,10.123,0.0,11,212,222,1920,A
id2,72.234,11.111,,,312,342,1920,A
id3,77.832,12.111,1,0.0,,333,4520,B
id4,77.987,12.345,3,0.0,,231,2020,B
id5,77.111,13.099,5,11,212,222,1920,A
到目前为止的代码:
dfile = "data.csv"
missing_value = -999
import numpy as np
data = np.genfromtxt(dfile, unpack=True, comments='#', names=True,
autostrip='Yes', filling_values=missing_value,
dtype=('S5', 'float', 'float', 'float', 'float', 'float', 'float', 'S1')
, delimiter=',',
)
new_data = np.where(data!=0.0 ,data, -999)
我使用了np.where(data!= 0.0,data,-999),但出现错误:TypeError: invalid type promotion
我不知道自己在想什么...
ps 1.也许它可以用熊猫解决,但我正在寻找独立的解决方案
ps 2.我知道一个肮脏的解决方法是在初始文件中将不正确的值(0.0s)设置为我的丢失标志,但是我们想排除多个值是什么? (或将数据与不同的标志合并)
答案 0 :(得分:1)
定义一个简单的文本:
In [55]: txt= '''foo,bar,test
...: a,1,2
...: b,3,4
...: '''
加载genfromtxt
:
In [60]: data = np.genfromtxt(txt.splitlines(), encoding=None, names=True, dtype=None, delimiter=',')
In [61]: data
Out[61]:
array([('a', 1, 2), ('b', 3, 4)],
dtype=[('foo', '<U1'), ('bar', '<i8'), ('test', '<i8')])
请注意dtype-具有不同dtype和名称的字段。
按名称访问字段:
In [64]: data['foo']
Out[64]: array(['a', 'b'], dtype='<U1')
通过索引修改一个字段:
In [65]: data['bar']
Out[65]: array([1, 3])
In [66]: data['bar'][0] = 23
使用布尔测试(或where
)修改另一个:
In [67]: test = data['test']
In [68]: test
Out[68]: array([2, 4])
In [69]: test==2
Out[69]: array([ True, False])
In [70]: test[test==2]=0
In [71]: test
Out[71]: array([0, 4])
In [72]: data
Out[72]:
array([('a', 23, 0), ('b', 3, 4)],
dtype=[('foo', '<U1'), ('bar', '<i8'), ('test', '<i8')])
如果将数字字段分组为一个字段,替换可能会更容易(但这需要更多地了解结构化数组dtypes):
In [80]: data = np.genfromtxt(txt.splitlines(), encoding=None, skip_header=1, dtype=[('id','U3'),('foo',int,2)],
...: delimiter=',')
In [81]: data
Out[81]:
array([('a', [1, 2]), ('b', [3, 4])],
dtype=[('id', '<U3'), ('foo', '<i8', (2,))])
In [82]: data['foo']
Out[82]:
array([[1, 2],
[3, 4]])
答案 1 :(得分:0)
在我看来,问题出在np.genfromtxt部分。它创建以下形式的numpy数组:
np.array([np.void, np.void ... ])
这导致np.where失败。解决此问题的一种方法是:
data = np.array([[i for i in j] for j in data])
我认为这不是一个很好的解决方案。但这应该可以起作用,直到有人给出真正的答案为止。