python - 与 matlab 相比,数据传输到数组的问题和访问数据时的速度很慢
问题描述
我正在尝试将代码从 matlab 移植到 python,我的主要问题是读取文件并将数据转换为数组。在matlab中:
[filename,pathname,~] = uigetfile('*.out');
data{1} = importdata(fullfile(pathname,filename), '\t', 8);
unit = dados{1}.colheaders;
title = strsplit(char(dados{1}.textdata(7,1)));
在蟒蛇中:
import tkinter.filedialog
import numpy as np
def openfile():
file_path = tkinter.filedialog.askopenfile(mode='r', filetypes=[('','.out')])
data=np.loadtxt(file_path,delimiter='\t',skiprows=8)
nrows, ncols = np.shape(data)
return data, nrows, ncols
data, nrows, ncols = openfile()
print(data[0:5][0])
但是当我尝试访问第一列(时间向量)然后打印这个向量时,我得到了一行的打印。即使我将索引从 [0:5][0] 反转为 [0][0:5] 我也得到了类似的结果。另一个问题是访问文件比在 matlab 中花费的时间要长得多。下面是我试图在 python 中访问的数据示例。
#
Predictions were generated on 07-Jun-2021 at 07:36:56 using OpenFAST, compiled as a 64-bit application using double precision at commit v2.5.0
linked with NWTC Subroutine Library; ElastoDyn; InflowWind; AeroDyn; ServoDyn; HydroDyn; MoorDyn (v1.01.02F, 8-Apr-2016)
Description from the FAST input file: IEA 15 MW offshore reference model on UMaine VolturnUS-S semi-submersible floating platform
Time NcIMUTVxs NcIMUTVys NcIMUTVzs NcIMUTAxs NcIMUTAys NcIMUTAzs NcIMURVxs NcIMURVys NcIMURVzs NcIMURAxs NcIMURAys NcIMURAzs
(s) (m/s) (m/s) (m/s) (m/s^2) (m/s^2) (m/s^2) (deg/s) (deg/s) (deg/s) (deg/s^2) (deg/s^2) (deg/s^2)
0.0000 0.000E+00 0.000E+00 0.000E+00 -7.319E-01 -3.911E-01 -1.344E+00 0.000E+00 0.000E+00 0.000E+00 4.008E+00 -1.493E+01 4.163E-01
0.0250 -1.818E-02 -9.621E-03 -3.261E-02 -6.358E-01 -3.754E-01 -1.210E+00 9.613E-02 -3.609E-01 9.976E-03 3.542E+00 -1.345E+01 3.672E-01
0.0500 -3.140E-02 -1.845E-02 -5.898E-02 -5.513E-01 -3.181E-01 -9.064E-01 1.709E-01 -6.537E-01 1.772E-02 2.361E+00 -9.933E+00 2.434E-01
0.0750 -4.459E-02 -2.540E-02 -7.653E-02 -3.923E-01 -2.385E-01 -4.594E-01 2.103E-01 -8.428E-01 2.174E-02 7.456E-01 -4.845E+00 7.446E-02
0.1000 -5.177E-02 -3.032E-02 -8.156E-02 -2.350E-01 -1.594E-01 5.288E-02 2.078E-01 -8.920E-01 2.140E-02 -9.449E-01 9.618E-01 -1.022E-01
解决方案
numpy.loadtxt
通常,效率不是很高(numpy 保存/加载最适合二进制格式)。另外,您的代码原样对我不起作用(因为分隔符不是真正的制表符,而是多个空格,我认为 numpy 不支持)。
在你的位置,我会使用原始 python(然后转换为 numpy 数组)或 pandas(可能更慢但更健壮)。
忽略 tkinter 部分并假设文件名是data.txt
,第一个解决方案如下所示:
import numpy as np
data = []
with open('data.txt') as fp:
for i, line in fp:
if i >= 8:
data.append([float(x) for x in line.split()])
data = np.asarray(data)
pandas 的第二个解决方案是:
import pandas as pd
df = pd.read_csv('data.txt', skiprows=7, delimiter=' ', skipinitialspace=True)
data = df.values
结果是等价的,但略有不同:python 的split
函数会自动修剪开头和结尾的空白,另外它会将任何空白视为一个分隔符(一个空格、多个空格、制表符等)。在您提供的示例中转换为float
有效。跳过所有前 8 行。Pandas 的版本也忽略了多个空格,但我认为它不适用于制表符,而且我们需要明确告诉它忽略行首的空格。我们也只是跳过 7 行,而不是 8 行,因为默认情况下 csv 文件必须在第一列中有列名。所以在这种特殊情况下,我们会得到一个带有列名的数据框
['(s)', '(m/s)', '(m/s).1', '(m/s).2', '(m/s^2)', '(m/s^2).1',
'(m/s^2).2', '(deg/s)', '(deg/s).1', '(deg/s).2', '(deg/s^2)',
'(deg/s^2).1', '(deg/s^2).2']
但这并不重要,因为当我们最后取.values
时,只保留数值。
也许,更重要的区别是,如果在某个地方(例如,字符串)存在无效值,python 的代码会在尝试转换为 float 时引发异常,pandas 的解决方案会很乐意接受它并创建一个 " object”类型(即“anything”类型),甚至不将有效条目转换为浮点数(在该列中)。
推荐阅读
- react-native-android - 使用 react-native-paypal-lib 反应原生 Paypal 支付网关
- sprite-kit - 无法使用 SKVideoNode 播放视频,但可以听到声音
- php - 未捕获的 SoapFault 异常:[HTTP] Forbidden
- javascript - forEach 在客户端使用单个文档 Firebase 查询?
- c# - 使用 windows 多媒体 (winmm.dll) 获取设备(操纵杆)guid
- c - 计算对数的平均值
- react-native - 模块'react-navigation'在急速模块地图中不存在
- mysql - 我如何知道哪些事务首先运行
- android - 在默认拨号器应用程序的情况下如何从其他应用程序中获取电话号码?
- python - 如何将特征分别输入到 LSTM 模型