首页 > 解决方案 > 如何将矩阵形式的 txt 文件加载为浮点类型?

问题描述

我有一个由 159 * 29 矩阵组成的 txt 文件。

我想将此矩阵作为浮点数并将其存储为 np.array 格式。

问题是我的文本文件包含 [,]。

让我向您展示一些我的文本文件作为示例。请帮忙。谢谢你。

    ex.txt

    [[1.31884812e-01 4.85885328e-02 5.17866485e-02 9.24929814e-02
    9.42103216e-02 8.50022142e-02 8.57238412e-02 9.96234015e-02
    1.14856198e-01 1.11659724e-01 9.72807538e-02 9.20717962e-02
    9.12622858e-02 9.68798360e-02 1.12404521e-01 1.13864315e-01
    1.05420802e-01 1.01923343e-01 9.82294570e-02 9.85429105e-02
    1.06702456e-01 1.12663644e-01 1.19183466e-01 1.14763882e-01
    1.05617832e-01 1.02883940e-01 9.24510572e-02 8.78869806e-02
    9.66031440e-02 9.68025400e-02 1.01009777e-01 1.51004856e-01
    1.26032222e-01 4.83166563e-02 5.56340695e-02 8.56342866e-02
    8.71916453e-02 9.30664908e-02 1.00653943e-01 1.06950373e-01
    9.98731406e-02 9.03583575e-02 1.00146412e-01 1.10677896e-01
    1.09498884e-01 1.06648914e-01 1.10096858e-01 1.10210797e-01
    1.03439199e-01 1.03742909e-01 1.01274575e-01 9.87265900e-02
    1.08099849e-01 1.05718825e-01 9.43474858e-02 9.37020526e-02
    9.37328738e-02 9.00777858e-02 9.18707559e-02]
    [1.27356767e-01 9.50714549e-03 3.51917853e-02 5.60814608e-02
    4.67684941e-02 4.37193897e-02 3.94782008e-02 5.10511578e-02
    6.00998918e-02 6.40744212e-02 4.29009335e-02 5.26423953e-02
    4.14972762e-02 5.27328912e-02 5.29212138e-02 6.73998829e-02
    4.36410294e-02 5.64574948e-02 4.82356819e-02 4.65436714e-02
    5.58660110e-02 5.69371838e-02 6.07319187e-02 6.36302760e-02
    5.00506026e-02 5.59908535e-02 4.59377176e-02 4.20365157e-02
    4.84277908e-02 5.26725503e-02 4.13320813e-02 9.17620584e-02
    1.30050386e-01 5.62320480e-03 4.76918484e-02 4.19101014e-02
    4.46161651e-02 4.69018429e-02 4.94103807e-02 5.88036867e-02
    5.35074724e-02 3.88601964e-02 5.39223099e-02 5.59319300e-02
    5.42011542e-02 5.30993292e-02 5.70689604e-02 5.82497387e-02
    5.27066529e-02 5.17498580e-02 5.38496575e-02 4.50412685e-02
    5.53325257e-02 5.82311744e-02 4.09089357e-02 5.18904344e-02
    4.73671715e-02 4.49264348e-02 4.76753951e-02]
    [1.19440276e-02 1.74260751e-02 3.50030488e-03 1.25507823e-03
    6.39962770e-04 7.58302240e-05 3.95251462e-04 1.09434956e-03
    3.19130608e-04 1.10887705e-03 1.69392836e-03 5.28743182e-04
    ...

标签: python

解决方案


数据不适合以 csv 格式读取,因此需要进行一些转换...

这假设文本中有换行符,就像您在上面的示例中那样。

>>> row_list = []
>>> row_data = []
>>> 
>>> for line in open("ex.txt", 'r'):
...     if '[' in line:
...         # New row.
...         row_data = []
...         row_list.append(row_data)
...         line = line.replace('[', '')
...     elif ']' in line:
...         line = line.replace(']', '')
...     vals = line.split()
...     row_data.extend(float(val) for val in vals)
>>> 

我没有在问题上看到 Pandas 或 numpy 标签,所以我没有包含任何代码来将结果数组放入数据框中。

row_list将是一个包含 59 个项目的列表。不是问题中所说的,但这是因为输入文本中定义的每个列表都有 59 个项目。如果您使用的是 numpy 或 pandas,则可以在从行数据创建数据框或 np 数组后对其进行整形。

将输入文本转换为列表列表的另一种方法。我不喜欢在处理它们之前将整个文件拉入内存,但这应该可行:

>>> txt = open("ex.txt", 'r').read()
>>> 
>>> txt = re.sub(r"([\de\-\.]+|\])", r"\1,", txt.strip())
>>> data = eval(txt)
>>> data = data[0]  # In case a tuple-of-lists-of-lists was returned.
>>>
>>> del txt   # Free up memory the file text was taking up.

然后数据应该是浮点值列表的列表。eval()这种方法修复了整个字符串的语法,因此在调用时它将成为列表列表。


“数字看起来很奇怪,有问题……”

我不止一次看到过这种情况,因为提交的答案被认为是错误的,因为数字在数据框或数组中的显示与它们在文本输入中出现的完全不一样。所以这值得一些解释。

有其他方法可以显示相同的值。如果数据框中的值的数据类型是浮点数,解释器(可能还有模块)决定在显示时表示它们的值的最佳方式。如果输入文本是'1.45e-04',解释器可以选择将其显示为0.000145。两者都代表相同的浮点值;它们只是替代形式。

假设我们有一些文本要用于构建数据框。人们可能期望他们的数据框看起来与输入数据相同。

>>> arr = """
...       foo             bar
...       1.31884812e-01  9.24929814e-02
...       9.42103216e-02  9.96234015e-02
...       1.14856198e-01  9.20717962e-02
...       """

所以,像这样将数据读入数据框......

>>> df = pd.read_csv(io.StringIO(arr), sep=r'\s+', dtype=str)
>>> df
              foo             bar
0  1.31884812e-01  9.24929814e-02
1  9.42103216e-02  9.96234015e-02
2  1.14856198e-01  9.20717962e-02

看起来一切都是正确的。请注意,dtype=str必须用于将这些值的格式保留为字符串。但是,如果需要使用这些值进行任何计算,这并不是很有用。

>>> df.dtypes
foo    object
bar    object
dtype: object

所以,我们想要一个带有浮点数的数据框......

>>> df = pd.read_csv(io.StringIO(arr), sep=r'\s+')
>>> df
        foo       bar
0  0.131885  0.092493
1  0.094210  0.099623
2  0.114856  0.092072

'哦,不......数据被破坏了!'......不,这就是那些值应该看起来的样子。它是转换为适当数据类型的同一组值。

>>> df.dtypes
foo    float64
bar    float64
dtype: object

'但我已经看到它在数字没有改变之前工作'..如果数字足够小,那么 interp(或模块)将选择也使用科学计数法显示值,并且它会以相同的方式显示作为数据框中的浮点值,就像在输入文本中一样。

>>> arr = """
...       foo             bar
...       1.31884812e-08  9.24929814e-08
...       9.42103216e-08  9.96234015e-08
...       1.14856198e-08  9.20717962e-08
...       """
>>> df = pd.read_csv(io.StringIO(arr), sep=r'\s+')
>>> df
            foo           bar
0  1.318848e-08  9.249298e-08
1  9.421032e-08  9.962340e-08
2  1.148562e-08  9.207180e-08

请注意,最后一个示例中的指数是 -8。这表示 10 的 -8 次方,这意味着小数点左移了很多次。解释器不想显示那么多的 0,所以它选择使用科学计数法,所以看起来很巧合。

看起来我们在数据框中显示值的方式失去了一些精度,但我们没有。解释器只是没有向您显示与输入文本相同的位数。

如果您想控制这些值在报告或图表中的显示方式,则可以将它们转换为字符串并使用字符串格式来选择要显示的小数位数以及数据是否采用科学计数法。

或者,str如果您只需要它来展示而不需要计算,则只需将数据框转换为。

>>> df.astype(str)
              foo             bar
0  1.31884812e-08  9.24929814e-08
1  9.42103216e-08  9.96234015e-08
2  1.14856198e-08  9.20717962e-08

推荐阅读