2017-06-08 2 views
0

/tldr名前が一致しない元の2つの名前の2つの名前(コンテナ+子)の連結である大きなファイル名のセットを解析します。 Pythonライブラリの提案やその他のガイダンスは高く評価されています。Pythonを使用して、一貫性のないオブジェクト名から連結された大きなファイル名のセットを解析します。

私は、文字列内の情報の命名法と書式設定がある程度矛盾する可能性がある情報のために文字列を解析する方法を探しています。

背景業種:
時系列データは、単一の.csvファイルに保存されている単一のデータポイントと自動化システムからエクスポートされる:自動化は

問題解決しようとする制御を行います。 (例:制御システムが環境制御システムであった場合、15分間隔で測定された部屋の測定温度となることがあります)。CSVファイルにエクスポートする数十点ある環境や、 CSVファイルにエクスポートする1​​000ポイント。ポイントが通常格納される構造は次のとおりです。ポイントはコントローラ内に含まれ、コントローラは管理システムの下に統合され、管理システムは別の管理システムに統合されることがあります。結果として得られる構造は、単純な階層ツリーです。

CSVファイルに関連付けられたファイル名は、次のように各ポイントのパス構造から組み立てられます。(必要に応じてネストされた)管理システム用のディレクトリが作成され、その下にファイル名が連結されたCSVファイルコントローラー名とポイント名。

私はCSVファイル(現在約5500個の[成長中])を構造化データストアに毎月エクスポートするpythonスクリプトを作成しました。現在、私はいくつかの実際の醜い正規表現や醜いstring.find()を使用しています。静的な文字列値のリストは、各ファイルのコントロール名とポイント名を解析するために入力します。構造化データストア。

上記のように、これらの環境で使用されている命名法はほとんど同じではありません。ポイント名は大きく異なります。上記のポイントは、ROOMTEMP、RM_T、RM-T、ROOM-T、ZN_T、ZNT、RMTまたは他のいくつかの可能性として知られているかもしれません。これは、コントローラ内のほとんどすべての点に適用されます。コントローラ名は、制御しているデバイスのタイプ、デバイスの地理的位置、またはデバイスに関連付けられているアセット番号などの名前が付けられている場合、やや矛盾します。

私は、新しい場所が追加されるたびにファイル名を解析する正規表現を書いているビジネスから抜け出したいと思っています。ファイル名を読み込んでパターンを探し、各ファイル名からコントローラ名とポイント名を解析するための推奨事項を作成するコードを記述したいと思います。私はすでに各ポイントオブジェクトにコントローラ名とポイント名を手で割り当てることができるインターフェースを持っているので、パーズにエラーがある場合は結果を変更できます。理想的には、既存のオブジェクトによって作成されたパターンは、解析される新しいファイルの推奨される名前に影響します。

次のようにファイル名のいくつかの例は次のとおりです。 UNIT1254_SAT.csv、UNIT1254_RMT.csv、UNIT1254_fil.csv、AHU_5311_CLG_O.csv、QE239-01_DISCH_STPT.csv、HX_E2_CHW_Return.csv、Plant_RM221_CHW_Sys_Enable.csv、TU_E7_Actual CLG Setpoint.csv、1725_ROOMTEMPを.csv、1725_DA_T.csv、1725_RA_T.csv

コントローラ名とポイント名を連結した順序は常に一致します。コントローラー名をポイント名(通常はアンダースコアですが、時にはダッシュやその他の文字)に区切るために一貫した文字が使用される可能性が最も高いでしょう。

これらのファイル名を解析する方法?私はいくつかのアイデアを考えましたが、パフォーマンスの問題の可能性を見つけ出したり、失敗点を特定したりするために、実装前に試してみる前に、棚上げしておきます。私のコードの残りの部分は、私が必要とする方法とほぼ同じです。ファイル名から正しい名前を引き出す効率的で便利な方法を見つけられませんでした。残念ながら、制御システム側の名前を一貫して変更することはできません。

+0

こんにちは。あなたの問題は大雑把にしか分かりませんでした。私は、ファイル名に存在するポイント名からコントロール名を分離したいという印象を受け取ります。名前の前提を持たずに、またファイル名に区切り文字がどこにあるのかを正確に知ることなく、 1つ(1つのコンテナ名)または2つ(2つのコンテナ名)。ただし、正規表現を作成し、str.find()と静的文字列値を使用します。最初にいくつかの情報があります。この情報は何ですか?もっと説明してください。 – eyquem

+0

ROOMTEMP、RM-T、RM-T、ROOM-T、RMTの間にはいくつかの類似点があります。しかし、ZN_TとZNTではなく、T! 5つの最初のものの間の類似性を検出する可能性はありますが、最後のものは2つではありません。 – eyquem

+0

コントローラと管理システムの構造を表す階層ツリーではなく、ファイル名だけを知っているようです。そうですか? – eyquem

答えて

0

次のコードが役立つかどうかわかりませんが、少なくともいくつか考えていただければ幸いです。 "QE239-01_STPT_1725_ROOMTEMP_DA" などのファイル名は以下の名前
'QE239-01'
'QE239-01_STPT'
'QE239-01_STPT_1725'
'QE239-01_STPT_1725_ROOMTEMP'
「QE239を含めることができることを考えると

-01_STPT_1725_ROOMTEMP_DA '
'STPT'
'STPT_1725'
'STPT_1725_ROOMTEMP'
'STPT_1725_ROOMTEMP_DA'
' 1725'
'1725_ROOMTEMP'
'1725_ROOMTEMP_DAファイル名の可能要素(コンテナ名またはポイント名)であるとして'
'ROOMTEMP'
'ROOMTEMP_DA'
'DA'
、 Iは機能treat()定義名前からこのリストを返す。

次に、コードはすべてのファイル名を処理して、ファイル名のすべての可能な要素を見つけます。 この例では、STPT_ROOMTEMPはこの2つの要素の間に1725が存在するため、この例の文字列で可能なコンテナ名ではないため、ROOMTEMP要素はSTPT要素の後に続かないという考え方に基づいています。

そして、difflibモジュールの機能の助けを借りて、いくつかの類似要素を区別して、名前のいくつかの要素を集めるパターンを検出しようとします。

あなたが面白い結果を得るために最も良いものを選ぶには、引数として渡された値をcutoffパラメータに渡して遊ぶ必要があります。

私はあなたの問題のすべての側面を理解していませんでした。

s =\ 
"""UNIT1254_SAT 
UNIT1254_RMT 
UNIT1254_fil 
AHU_5311_CLG_O 
QE239-01_DISCH_STPT, 
HX_E2_CHW_Return 
Plant_RM221_CHW_Sys_Enable 
TU_E7_Actual Clg Setpoint 
1725_ROOMTEMP 
1725_DA_T 
1725_RA_T 
UNT147_ROOMTEMP 
TRU_EZ_RM_T 
HXX_V2_RM-T 
RHXX_V2_ROOM-T 
SIX8_ZN_T 
Plint_RP228_ZNT 
SOHO79_EZ_RMT""" 

li = s.split('\n') 
print(li) 
print('- - - - - - - - - - - - - - - - - ') 

import difflib 
from pprint import pprint 

def treat(name): 
    lu = name.split('_') 
    W = [] 
    while lu: 
     W.extend('_'.join(lu[0:x]) for x in range(1,len(lu)+1)) 
     lu.pop(0) 
    return W 

if 0: 
    q = "QE239-01_STPT_1725_ROOMTEMP_DA" 
    pprint(treat(q)) 
    print('==========================================') 

WALL = [] 
for t in li: 
    WALL.extend(treat(t)) 
pprint(WALL) 

for x in WALL: 
    j = set(difflib.get_close_matches(x, WALL, n=9000000, cutoff=0.7)) 
    if len(j)>1: 
     print(j,'\n') 
関連する問題