【问题标题】:Python: Save data with floats and strings with np.savetxtPython:使用 np.savetxt 保存带有浮点数和字符串的数据
【发布时间】:2013-10-31 16:50:54
【问题描述】:

我正在尝试保存一个包含浮点数和一列字符串的数组,但我得到了一些非常奇怪的结果。这是我尝试过的:

data = np.column_stack((f1, f2, f3, s1))

第一列 (f1) 是长浮点数(最多 10 位,但我只需要 2 位)。我还需要在第二列和第三列分别输入 2-3 位数字,f2f3。最后一列 s1 仅包含两个不同的字符串:'FeI''FeII'

问题是,当我尝试打印 data 时,我会得到这样的结果:

[['7352'  '11.7'  '-4.9'  'FeI']
 ...,
 ['5340'  '22.8'  '-8.2'  'FeII']]

虽然我想得到这样的东西(我不在乎它是否将浮点数保存为字符串,因为之后我可以轻松地将它们加载为浮点数):

[['7352.91'  '11.78'  '-4.92'  'FeI']
 ...,
 ['53407.66'  '22.82'  '-8.27'  'FeII']]

如您所见,主要问题是,它 53407.66 变成了 5340 - 一个数量级!

可能的解决方案 要改用np.array 并使用dtype-选项。但是,我不知道如何将列存储为字符串。有什么帮助吗?

【问题讨论】:

  • 何时以及如何打印数据?什么时候必须采用您指定的格式?

标签: python numpy types


【解决方案1】:

使用结构化数组来保存数据,而不是使用column_stack

假设这是您的数据:

In [30]: f1
Out[30]: array([ 12.3,  45.6,  78.9])

In [31]: f2
Out[31]: array([ 10.11,  12.13,  14.15])

In [32]: f3
Out[32]: array([ 1. ,  2.5,  5. ])

In [33]: s1
Out[33]: 
array(['foo', 'bar', 'baz'], 
      dtype='|S3')

以下是创建结构化数组的方法。第一个参数是一个元组列表。每个元组保存数组中每个结构化元素的值。 dtype 参数定义结构中字段的数据类型。在这种情况下,有三个浮点字段(名为“f1”、“f2”和“f3”)和一个字段(名为“s1”)包含最多 16 个字符的字符串:

In [34]: data = np.array(zip(f1, f2, f3, s1), dtype=[('f1', float), ('f2', float), ('f3', float), ('s1', 'S16')])

In [35]: data
Out[35]: 
array([(12.3, 10.11, 1.0, 'foo'), (45.6, 12.13, 2.5, 'bar'),
       (78.9, 14.15, 5.0, 'baz')], 
      dtype=[('f1', '<f8'), ('f2', '<f8'), ('f3', '<f8'), ('s1', 'S16')])

要控制使用np.savetxt 保存时的字段格式,您可以给它一个格式列表,每个字段一个:

In [36]: np.savetxt('output.txt', data, fmt=["%.3f",]*3 + ["%s"])

In [37]: !cat output.txt
12.300 10.110 1.000 foo
45.600 12.130 2.500 bar
78.900 14.150 5.000 baz

注意:要考虑的另一种选择是将数据放入pandas DataFrame,并使用其to_csv 方法。

【讨论】:

    【解决方案2】:

    使用 zip 的解决方案应该适用于大多数情况,但我认为它可能不是最有效的解决方案。此外,当其中一个数组的类型为 np.dateTime64 时,我遇到了一个小问题。这是使用熊猫的另一种解决方案...:

    import pandas as pd
    import numpy as np
    
    f1 = np.array([ 12.3,  45.6,  78.9])
    f2 = np.array([ 10.11,  12.13,  14.15])
    f3 = np.array([ 1. ,  2.5,  5. ])
    s1 = np.array(['foo', 'bar', 'baz'])
    d1 = np.array(['2015-04-30T02:58:22.000+0200', '2015-04-30T02:58:22.000+0200',
           '2015-04-30T02:58:22.000+0200'], dtype='datetime64[ms]')
    df = pd.DataFrame({
                'f1':f1,
                'f2':f2,
                'f3':f3,
                'str1':s1,
                'date':d1
    })
    df.to_csv('out.csv')
    

    【讨论】:

      【解决方案3】:

      为什么不对您存储的数据进行预处理? 喜欢

      f1 = ['{0:0.2f}'.format(str(item) for item in f1]
      f2 = ['{0:0.3f}'.format(str(item) for item in f2]
      f3 = ['{0:0.3f}'.format(str(item) for item in f3]
      

      如果您打算稍后使用它们,您应该只在打印出浮点数时将它们表示为字符串,而不是在将它们存储在数组中时。

      【讨论】:

        猜你喜欢
        • 2015-09-29
        • 2015-03-11
        • 2018-03-13
        • 1970-01-01
        • 2013-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-13
        相关资源
        最近更新 更多