【问题标题】:Data transfer problems to an array and slowness when access data compared to matlab与 matlab 相比,数据传输到数组的问题和访问数据时的速度很慢
【发布时间】:2021-09-03 23:01:20
【问题描述】:

我正在尝试将代码从 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)));

在python中:

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

【问题讨论】:

    标签: python pandas numpy matlab


    【解决方案1】:

    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)
    

    熊猫的第二种解决方案是:

    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 的解决方案会很乐意接受它并创建一个“对象”类型的列(即“任何东西”类型),甚至不将有效条目转换为浮点数(在该列中)。

    【讨论】:

      猜你喜欢
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 2019-11-16
      • 2021-07-12
      相关资源
      最近更新 更多