2016-10-01 39 views
0

这里是一个大的数据集,我有工作的一个片段:numpy如何处理具有不确定性值的数据文件,例如0.6499(6)?

# p* T*  P*   U*   P*_cs U*_cs Steps dt* 
0.1 6.0 0.6499(6) -0.478(2) 0.6525 -0.452 30000 0.002 
0.2 6.0 1.442(1) -0.942(2) 1.452 -0.890 30000 0.002 
0.3 6.0 2.465(3) -1.376(1) 2.489 -1.298 30000 0.002 
0.4 6.0 3.838(5) -1.785(3) 3.880 -1.681 20000 0.002 
0.5 6.0 5.77(1) -2.131(3) 5.84 -2.000 20000 0.002 
0.6 6.0 8.51(2) -2.382(5) 8.60 -2.225 20000 0.002 
0.7 6.0 12.43(2) -2.501(4) 12.56 -2.318 20000 0.002 
0.8 6.0 18.05(2) -2.416(4) 18.22 -2.207 20000 0.002 
0.9 6.0 26.00(2) -2.058(4) 26.21 -1.823 20000 0.004 
1.0 6.0 37.06(3) -1.361(6) 37.32 -1.100 20000 0.002 
1.1 6.0 52.25(2) -0.216(4) 52.57  0.072 20000 0.002 
1.2 6.0 72.90(5) 1.502(9) 73.28  1.816 20000 0.002 
1.25 6.0 85.71(5) 2.612(8) 86.12  2.939 20000 0.002 

加载使用np.loadtxt这组数据失败,因为不确定性的P *和U *值。是否有一个内置的工具来处理这个问题,以避免手动编辑数据文件?

我在看uncertainties包作为一个可能的解决方案,但我不知道numpy已经有这个东西。

+0

您可以编写一个转换器来剥离该()部分。另一种方法是将文件/行预处理器拆分为两列。 – hpaulj

回答

2
In [1]: txt=b"""# p* T*  P*   U*   P*_cs U*_cs Steps dt* 
    ...: 0.1 6.0 0.6499(6) -0.478(2) 0.6525 -0.452 30000 0.002 
    ...: 0.2 6.0 1.442(1) -0.942(2) 1.452 -0.890 30000 0.002 
    ...: 0.3 6.0 2.465(3) -1.376(1) 2.489 -1.298 30000 0.002""" 
In [2]: txt=txt.splitlines() 

txt是一个文件substitue(在PY3字节字符串)

In [3]: data=np.genfromtxt(txt, dtype=None, names=True) 
In [4]: data 
Out[4]: 
array([(0.1, 6.0, b'0.6499(6)', b'-0.478(2)', 0.6525, -0.452, 30000, 0.002), 
     (0.2, 6.0, b'1.442(1)', b'-0.942(2)', 1.452, -0.89, 30000, 0.002), 
     (0.3, 6.0, b'2.465(3)', b'-1.376(1)', 2.489, -1.298, 30000, 0.002)], 
     dtype=[('p', '<f8'), ('T', '<f8'), ('P', 'S9'), ('U', 'S9'), ('P_cs', '<f8'), ('U_cs', '<f8'), ('Steps', '<i4'), ('dt', '<f8')]) 

'P' 和 'U' 被加载为字符串,因为它们不能被解析为数字。

查阅(具有字节串再次)限定converter即剥去()部分

def rmvpar(astr): 
    return float(astr.split(b'(')[0]) 

In [9]: data=np.genfromtxt(txt, dtype=None, names=True, 
     converters={2:rmvpar, 3:rmvpar}) 
In [10]: data 
Out[10]: 
array([(0.1, 6.0, 0.6499, -0.478, 0.6525, -0.452, 30000, 0.002), 
     (0.2, 6.0, 1.442, -0.942, 1.452, -0.89, 30000, 0.002), 
     (0.3, 6.0, 2.465, -1.376, 2.489, -1.298, 30000, 0.002)], 
     dtype=[('p', '<f8'), ('T', '<f8'), ('P', '<f8'), ('U', '<f8'), ('P_cs', '<f8'), ('U_cs', '<f8'), ('Steps', '<i4'), ('dt', '<f8')]) 

现在这两个字段是浮动。

但转换器不能返回两个数字,所以我不能保持这种不确定性。

另一种方法是通过一个过滤器功能,通过该行

def splt(astr): 
    strs=astr.split() 
    def foo(astr): 
     if b'(' in astr: 
      astr = astr.strip(b')').split(b'(') 
      return b','.join(astr) 
     return astr 
    return b','.join([foo(a) for a in strs]) 

In [26]: [splt(line) for line in txt] 
Out[26]: 
[b'#,p*,T*,P*,U*,P*_cs,U*_cs,Steps,dt*', 
b'0.1,6.0,0.6499,6,-0.478,2,0.6525,-0.452,30000,0.002', 
b'0.2,6.0,1.442,1,-0.942,2,1.452,-0.890,30000,0.002', 
b'0.3,6.0,2.465,3,-1.376,1,2.489,-1.298,30000,0.002'] 

要使用此我不得不跳过头,因为新的生产线有两个附加列

In [28]: data=np.genfromtxt([splt(line) for line in txt], delimiter=',',dtype=None, skip_header=1) 
In [29]: data 
Out[29]: 
array([(0.1, 6.0, 0.6499, 6, -0.478, 2, 0.6525, -0.452, 30000, 0.002), 
     (0.2, 6.0, 1.442, 1, -0.942, 2, 1.452, -0.89, 30000, 0.002), 
     (0.3, 6.0, 2.465, 3, -1.376, 1, 2.489, -1.298, 30000, 0.002)], 
     dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<f8'), ('f3', '<i4'), 
      ('f4', '<f8'), ('f5', '<i4'), ('f6', '<f8'), ('f7', '<f8'), 
      ('f8', '<i4'), ('f9', '<f8')]) 

但我可以修改原来的dtype使2个字段(子)阵列:

In [30]: dt=np.dtype([('p', '<f8'), ('T', '<f8'), ('P', '<f8',(2,)), 
       ('U', '<f8',(2,)), ('P_cs', '<f8'), ('U_cs', '<f8'), 
       ('Steps', '<i4'), ('dt', '<f8')]) 

In [31]: data = np.genfromtxt((splt(line) for line in txt), delimiter=',',dtype=dt, skip_header=1) 
In [32]: data 
Out[32]: 
array([(0.1, 6.0, [0.6499, 6.0], [-0.478, 2.0], 0.6525, -0.452, 30000, 0.002), 
     (0.2, 6.0, [1.442, 1.0], [-0.942, 2.0], 1.452, -0.89, 30000, 0.002), 
     (0.3, 6.0, [2.465, 3.0], [-1.376, 1.0], 2.489, -1.298, 30000, 0.002)], 
     dtype=[('p', '<f8'), ('T', '<f8'), ('P', '<f8', (2,)), ('U', '<f8', (2,)), 
      ('P_cs', '<f8'), ('U_cs', '<f8'), ('Steps', '<i4'), ('dt', '<f8')]) 

这样的场会是什么样子:

In [33]: data['P'] 
Out[33]: 
array([[ 0.6499, 6. ], 
     [ 1.442 , 1. ], 
     [ 2.465 , 3. ]]) 

我可以定义其他dtypes,就像只要字段的数量相匹配。

有了文件,而不是这些文本行,我会使用类似(未测试):

with open(filename,'wb') as f: 
    data = np.genfromtxt((splt(line) for line in f),... 

这里,以上,我使用发电机表达(splt(line) for line in x),虽然列表解析会没事的。任何打开文件并产生/返回修改过的行的代码都可以工作。

+0

这提供了一个有效的方法来消除不确定性。保持不确定性的方法需要稍加修改,以指定不确定性的十进制值(即第一个值0.6499(6)应该转换为0.6499 +/- 0.0006)。虽然这有点复杂,因为小数位数在值之间不一致,可以推断出来。这很好,谢谢! –

+0

我以前没有见过使用数据标签来索引一个NumPy数组。更像熊猫。太好了! –

1

不,在NumPy中没有这样的东西。您将需要一个外部包(即使熊猫不会这样做),或者您可以将这些列加载为字符串而不是数字并自行处理。对于字符串方法,Pandas中的str方法会有一些用处,例如, http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.str.split.html

所有这一切说,它甚至不清楚一旦数据加载后,你会如何表示。你想简单地忽略括号吗?你想在附加列中记录不确定数字的数量吗?这两种都是可能的,并且在Pandas中可能比NumPy更容易。

+0

我很高兴要么忽略它,要么将它添加到另一列。在报告错误时,另一列看起来很常见。这对NumPy或Pandas来说是一个很好的补充。 –

+0

@ stvn66:我可以肯定地告诉你,这绝不会被添加到NumPy中,并且它不太可能被添加到Pandas中,除非您能够证明它是大量用户广泛采用的标准或约定。 –

相关问题