2017-02-03 15 views
0

私はMatlabからPythonに移行しています。matlabのデータ構造から来るPythonを使用する

Matlabではデータを構造体で構造化しました。 新しいデータセットを取得するために操作したいデータがあります。

私はポンプから測定しています。特定のケースでは22ポイントがありますが、これはもちろんケースごとに異なります。

私はExcelシートのデータを列で構成しています。各データポイントについて、フロー(q)、高さ(h)、トルク(トルク)、および回転数(rpm)があります。私はxlrdを使ってデータを読んでいますが、これはうまくいきます。私は4つのキーで値を持つ辞書を作成します。

特定のデータセットポイントを操作するために使用できるスケーリングルールがいくつかあります。 Matlabでは、私はデータをhydraulic_dataという構造ファイルに編成しました。次に、hydraulic_data.qなどの4つのベクトルがあります。

最初のアプローチは、Pythonでdictを使用していました。ここで問題となるのは、キーの長さが定義されている、つまりリストにデータを追加できないということです。

私は空の辞書を作成しました。入力データと同じ長さのnp.zerosベクトルで埋められます。しかし、これは私にとってはうまくいかないようです。単純化された関数を以下に示す。

def test_for_loop(hydraulic_geometric_scaled): 
    import math 
    import numpy as np 
    no_of_points = len(hydraulic_geometric_scaled['q']) 
    zero_vector = np.zeros(no_of_points) 
    q = np.zeros(no_of_points) 
    h = np.zeros(no_of_points) 
    torque = np.zeros(no_of_points) 
    rpm = np.zeros(no_of_points) 
    hydraulic_scaling_max = {} 
    hydraulic_scaling_max['q'] = zero_vector 
    hydraulic_scaling_max['h'] = zero_vector 
    hydraulic_scaling_max['torque'] = zero_vector 
    hydraulic_scaling_max['rpm'] = zero_vector 
    rpm_max=6000 
    for i in range(no_of_points): 
     omega = hydraulic_geometric_scaled['rpm'][i]/60*2*math.pi 
     omega_max = rpm_max/60*2*math.pi 
     hydraulic_scaling_max['q'][i]= hydraulic_geometric_scaled['q'][i]*(omega_max/omega) 
     hydraulic_scaling_max['h'][i]= hydraulic_geometric_scaled['h'][i]*(omega_max/omega)**2 
     hydraulic_scaling_max['torque'][i]= hydraulic_geometric_scaled['torque'][i]*(omega_max/omega)**2 
     hydraulic_scaling_max['rpm'][i]= omega_max*60/2/math.pi 
    return hydraulic_scaling_max 

これは、各キーに同じ値のhydraulic_scaling_max辞書を返します。 Matlabでは、これはうまく動作しますが、明らかにここでは動作しません。その後、私は同僚と少し話をし、代わりにクラスを使うべきだと彼は提案しました。

私の質問: 1. Matlabの構造体としてdictを使うのは間違った方法ですか? (私は検索しており、明確な答えはないようです)。 2.コードがすべてのキーで同じことを私に与えるのはなぜですか? 3.クラスは最善の方法ですか?

私はPythonを最も使いやすい方法で使い始めることができたらうれしいですね。

+2

「キーの長さが定義されている、つまりリストにデータを追加できないという問題がありますか」を明確にすることはできますか?私はここであなたが何を言っているのか分かりません。あなたが遭遇している問題を見つけるのに役立つかもしれません。 – MarkHarley

+0

@MarkHarley:私は彼がサイズ変更可能でないnumpy配列を参照していると確信しています – TheBlackCat

答えて

0

私はあなたの最後の質問にまず答えます:これを実装する最も良い方法は、pandas DataFrameです。エクセルのスプレッドシートを直接DataFrameとしてインポートし、必要に応じて列を追加することができます。だから、既存のデータに列を追加するには、このような何かを行うことができます。

from math import pi 
import pandas as pd 

# load the excel file, you will need to adjust this to fit your file 
hydraulic_geometric_scaled = pd.read_excel('filename.xls') 

rpm_max=6000 
omega_max = rpm_max/60*2*pi 

omega = hydraulic_geometric_scaled['rpm']/60*2*pi 

# you re-use this a lot so it is faster to define it once 
factor = omega_max/omega 

# copy the columns you want, and apply the scaling factors 
hydraulic_scaling_max = hydraulic_geometric_scaled.loc[:,('q','h','rpm','torque')]*[factor, factor**2, 1, factor**2] 

# overwrite this column with constant values 
hydraulic_scaling_max['rpm'] = rpm_max 

あなたがこれを処理するクラスを作ることができますが、パンダのデータフレームを使用して、外の必要なものを行いますので、それははるかに複雑になります-ボックス。 Pythonにはたくさんの既製ツールがあるので、何かしたいのであれば、いつも他の誰かがそれをしていないことを確認してください。おそらく1つまたは複数のツールがすでに利用可能であり、そこで90%の道を得ることができます。

最初の質問では、本当にdictをMATLAB構造体として使用したいと思ったら、これはあなたがやる方法です。しかし、一般的に構造体としてdictを使いたくないのであれば、pandas DataFramsとxarrayはMATLAB構造体の置き換えとしてはるかに適しており、MATLAB構造体よりはるかに強力です。その理由は、あなたが5つの変数、zero_vectorqhtorque、およびrpmを定義しているが、あなたがしかzero_vectorを使用することで、あなたの2番目の質問については

。MATLABでは、それを構造体に4回置くと配列のコピーが作成されるため、4倍のメモリが必要ですが、1つのコピーの変更は他のものに影響しません。

しかし、1つの配列を4つのpython dict値に入れると、コピーは作成されません。これらのdictキーのそれぞれは、同じ配列の異なる名前であると言う方が良いでしょう。したがって、どのキーにアクセスしても、同じ基本配列を変更することになります。あなたは名前とニックネームを持っていて、名前とニックネームであなたを呼んでいる人は同じ人を指していると言います。これらの配列と同じです。定義した4つの異なる変数を使用するか、zero_array.copy()を使用してコピーを作成する必要があります。

MATLABのアプローチは、大きなアレイのパフォーマンスを犠牲にして、最初は少し明るいです。

また、これは疑問ではありませんでしたが、matlabでは行列のサイズを変更することができますが、numpyは配列のサイズを変更できません。なぜなら、Pythonはその機能についてもっと前向きな傾向があるからです。厳密に言えば、MATLABもPythonも配列のサイズを変更することはできません。 MATLAB のように見せかけています。実際にサイズ変更可能なデータ構造ではないため、サイズを変更することができます。しかし、実際には何が起きているのか、MATLABは実際にはループのたびに完全に新しい配列を作成し、すべてのデータを新しい配列にコピーしてから、ある時点で古い配列のメモリを解放しています。これは非常に遅いため、MATLABエディタはこれをしないよう警告します。同じ問題は実際には構造体に新しいフィールドを追加するときに発生しますが、通常はフィールド数が少なくなるため、これは多くの場合問題ではありません。

Pythonの主な哲学の1つは、「あなたのユーザーに嘘をつけるべきではない」ということです。この場合、あなたができないことをやっていないことを意味します。だからnumpyは実際にコピーを作成しているときに配列のサイズを変更することができないふりをしていません。データを新しい配列にコピーする場合は、明示的に行う必要があります。

また、MATLABのアプローチは、パフォーマンスが低下したりメモリ不足のエラーが発生したり、ハード検出やハードが発生するリスクが高いことを示すのが難しくなりますエラーをデバッグします。

また、Pythonにはサイズ変更可能なデータ構造があります。 Pythonのリストとpythonのdict(と他の多くのデータ型)の両方を、コピーを作成することなくサイズ変更することができます。だから実際にそうでないものにふりをするためには気が狂っている必要はありません。

関連する問題