2017-04-01 8 views
2

ファイルに次のように多くのレコードがあるとします。複数の列でレコードを並べ替えるPythonic方法

10.10.10.10(tcp/443) : Some SSL Vulnerability : Medium : Patched

10.10.10.11(tcp/888) : Some RCE Vulnerability : High : Not Patched

これらのレコードは、値Critical, High, Medium, Lowと3列を持っています。

これらのレコードをこのようにソートするには、どうすればよいでしょうか。 1.クリティカル、2.ハイ、3.ミディアム4.低?

+1

どのように?具体的には、[IntEnum](https://docs.python.org/3/library/enum.html#intenum)です。 –

+0

データをリストに読み込んでソートされたリストデータをファイルに書き戻す方法がわかっているとしますか?この問題を解決しようとしていることを示す[mcve]を投稿する必要があります。純粋なPythonソリューションが必要ですか?またはパンダを使用したいですか? –

答えて

1

Critical, High, Medium, Low文字列を数値に変換するための辞書を使用した純粋なPythonソリューションです。その数値はlist.sortのソートキー関数の引数として使用されます。私の主要な機能はまた、各レコードの最初のフィールドをセカンダリソートキーとして使用するので、グレード別にソートされた各セクションでは、エントリもその最初のフィールドでソートされます。

あなたの質問は、私はいくつかの簡単な偽のデータを構築してきたサンプルデータの2行が含まれているため。 [列挙](https://docs.python.org/3/library/enum.html)について

data = '''\ 
00 : abc : Low 
01 : def : High 
02 : ghi : Low 
03 : jkl : Medium 
04 : mno : High 
05 : pqr : Medium 
06 : stu : High 
07 : vwx : Medium 
08 : yza : High 
09 : bcd : High 
10 : efg : High 
11 : hij : Critical 
12 : klm : Critical 
13 : nop : Medium 
14 : qrs : High 
15 : tuv : Critical 
'''.splitlines() 
data = [row.split(' : ') for row in data] 

grades = {'Critical': 1, 'High': 2, 'Medium': 3, 'Low': 4} 

data.sort(key=lambda t: (grades[t[2]], t[0])) 
for row in data: 
    print(' : '.join(row)) 

出力

11 : hij : Critical 
12 : klm : Critical 
15 : tuv : Critical 
01 : def : High 
04 : mno : High 
06 : stu : High 
08 : yza : High 
09 : bcd : High 
10 : efg : High 
14 : qrs : High 
03 : jkl : Medium 
05 : pqr : Medium 
07 : vwx : Medium 
13 : nop : Medium 
00 : abc : Low 
02 : ghi : Low 
1

あなたが(例えば、pandas.read_csvを使用して)パンダのデータフレームにあなたのテーブルを変換することができた場合は、これが仕事をする:最初df

import pandas as pd 
df=pd.DataFrame({'a':[1,2,3,4,5,6],'b':['a','b','c','d','e','f'],'val':['critical','high','low','medium','critical','low']}) 
df['val'] = pd.Categorical(df['val'],['critical','high','medium','low']) 
df.sort_values(by='val',inplace=True) 

その後は

a b val 
0 1 a critical 
1 2 b high 
2 3 c low 
3 4 d medium 
4 5 e critical 
5 6 f low 

ました最後にdf

a b val 
0 1 a critical 
4 5 e critical 
1 2 b high 
3 4 d medium 
2 3 c low 
5 6 f low 

です。I nは、上記のコードは、順序を指定した行は、辞書のリストについてIntEnumを用い

2
df['val'] = pd.Categorical(df['val'],['critical','high','medium','low']) 

例でした。

from enum import IntEnum 
class Vulnerability(IntEnum): 
    CRITICAL = 1 
    HIGH = 2 
    MEDIUM = 3 
    LOW = 4 

records = [] 
records.append({'v': Vulnerability.MEDIUM}) 
records.append({'v': Vulnerability.HIGH}) 
records.append({'v': Vulnerability.CRITICAL}) 
records.append({'v': Vulnerability.LOW}) 

print(records) 
# [{'v': <Vulnerability.MEDIUM: 3>}, {'v': <Vulnerability.HIGH: 2>}, {'v': <Vulnerability.CRITICAL: 1>}, {'v': <Vulnerability.LOW: 4>}] 

print(records[0]['v'] < records[1]['v']) 
# False 

print(sorted(records, key = lambda k: k['v'])) 
# [{'v': <Vulnerability.CRITICAL: 1>}, {'v': <Vulnerability.HIGH: 2>}, {'v': <Vulnerability.MEDIUM: 3>}, {'v': <Vulnerability.LOW: 4>}] 
関連する問題