python - 如何将矩阵形式的 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
...
解决方案
数据不适合以 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
推荐阅读
- android - 应用程序关闭后如何保持套接字连接打开?
- android - 如何在 Android API 21 上使用 NMEA 协议?
- android - 服务内的 Android 版 MapBox
- oracle - 我在哪里可以找到 Oracle Cloud 中的 Rest API Endpoint?
- asp.net - ADFS 本机应用程序访问令牌缺少声明
- node.js - 从节点 js 服务器文件向浏览器添加 cookie
- vue.js - 带有 Vue 的电子应用程序抛出未捕获的错误:ENOENT
- c# - 动态添加的组合框项目对象不会引发更改通知
- spring-boot - 为什么 Spring Integration 中的 TIMESTAMP 和 ID 标头在 Spring Kafka 中未映射?
- sql - Oracle Sql - 今天获取查询结果比昨天慢得多