質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

0回答

409閲覧

レコードのパース処理後に同じ分類に分けられたデータは連結したい

zenji0705

総合スコア69

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/05/12 06:25

編集2020/05/13 01:30

閲覧いただきありがとうございます。

python3でコーディングしており、2種類の区切り('|'と':')文字で構成されたレコードを分割し、分類コードを付与してレコードをグループ分けしようと考えています。

下記にデータイメージを記載します。最初に、'|'でパースして要素を分けて、「品物」という項目と「グループ」という項目に対して、分類コードを付与します。「品物」と「グループ」の分類コードが一致している場合は同一レコードに出力して、異なる場合は別レコードとして出力したいです。

※ソースを記載しました。データイメージと記述内容が異なっていますが、読み替えてくれると助かります。

やりたいことは、愚直にfor文で分類分けしているロジックをもっと効率する方法はないか。
現状だと数万件のデータが来たらかなり遅い処理になると予想しているので改善したいのです。

大変恐縮ですが、アドバイスいただけると助かります。

###データイメージ
【項目名】'注文No' | '品物' | 'グループ'
注文001 | みかん:りんご:ピーマン | くだもの:やさい
注文002 | みかん:レシート |
注文003 | | くだもの:やさい
注文004 | ピーマン:レタス| やさい:たべもの

###理想の結果イメージ
【項目名】
'注文No','品物','グループ','分類コード'

注文001,みかん:りんご ,くだもの,1
注文001,ピーマン   ,やさい ,2
注文002,みかん    ,    ,1
注文002,領収書   ,     ,99
注文003, ,くだもの,1
注文003, ,やさい ,2
注文004,ピーマン:レタス,やさい:たべもの,2

###ソース

pyhon3

1def logDistribution(value): 2 """ 3 ログ分類処理  4 :param value: チェック対象の文字列 5 """ 6 # dos 7 chk = re.match(r"^IPBLOCK-*", value) 8 if chk: 9 return '4' 10 11 # bot manager 12 chk = re.match(r"^39", value) 13 if chk: 14 return '2' 15 chk = re.match(r"^BOT-", value) 16 if chk: 17 return '2' 18 19 # client reputation 20 chk = re.match(r"^REP_", value) 21 if chk: 22 return '3' 23 24 # API Protection 25 chk = re.match(r"^API_", value) 26 if chk: 27 return '6' 28 29 # UA filter 30 chk = re.match(r"^6", value) 31 if chk: 32 return '7' 33 34 # no match 35 return '1' 36 37def log_parser(): 38 test_file = 'C:\tmp/sample_apache_log.txt' 39 40 reader = pd.read_csv(test_file, sep='\n', chunksize=50,header=None) 41 for row in reader: 42 regex = '([(\d.)]+) - - [(.*?)] "(\S+?)(?: +(.*?) +(\S*?))?" (\d+) (\d+) "(.*?)" "(.*?)" "(.*?)" "(.*?)"' 43 44 pd_result=row[0].str.extract(regex, expand=True) 45 # 46 print(pd_result.at[0,0]) 47 print(pd_result.at[0,1]) 48 print(pd_result.at[0,2]) 49 print(pd_result.at[0,3]) 50 print(pd_result.at[0,4]) 51 print(pd_result.at[0,5]) 52 print(pd_result.at[0,6]) 53 print(pd_result.at[0,7]) 54 print(pd_result.at[0,8]) 55 print(pd_result.at[0,9]) 56 print(pd_result.at[0,10]) #分類分けデータ 57 58 # policyID,ruleID,riskName 59 pd_result[[11,12,13]] = pd_result[10].str.split('|', expand=True) 60 61 # 複数カラムにまたがる処理を愚直にforでやってる(todo:改善したい) 62 for i, row in pd_result.iterrows(): 63 64 log_kind = 0 # init 65 if row[12] == [''] and row[13] == [''] : 66 log_kind = 5 # Access_log 67 print (row[10] + 'is :' +log_kind) 68 #pd_result.at[i, 14] = log_kind # ★★要デバッグ 69 continue 70 71 # RuleID 72 ruleID = row[12].split(':') 73 ruleID_dir = [] 74 75 if ruleID == ['']: 76 pass 77 else : 78 for rID in ruleID: 79 log_code = logDistribution(str(rID)) 80 ruleID_dir += [log_code] 81 82 # Risk Group Name 83 riskName = row[13].split(':') 84 riskName_dir = [] 85 86 if riskName == ['']: 87 pass 88 else: 89 for rName in riskName: 90 log_code = logDistribution(str(rName)) 91 riskName_dir += [log_code] 92 93 # ログの分割 94 Aggregation_dir = [] 95 if not ruleID_dir: 96 pass 97 else: 98 for i in range(len(ruleID_dir)): 99 tmp_dir = [ruleID_dir[i],ruleID[i],'',row[11]] 100 if i == 0: 101 Aggregation_dir.append(tmp_dir) 102 else : 103 # すでにAggregation_dirに登録されてる分類コードなら:で連結する 104 merge_flg = False 105 for j in range(len(Aggregation_dir)): 106 if Aggregation_dir[j][0] == tmp_dir[0]: 107 if not Aggregation_dir[j][1]: 108 Aggregation_dir[j][1] = tmp_dir[1] 109 merge_flg = True 110 else: 111 Aggregation_dir[j][1] = Aggregation_dir[j][1] + ':' + tmp_dir[1] 112 merge_flg = True 113 if merge_flg == False : 114 Aggregation_dir.append(tmp_dir) 115 if not riskName_dir: 116 pass 117 else: 118 for i in range(len(riskName_dir)): 119 tmp_dir = [riskName_dir[i],'',riskName[i],row[11]] 120 if i == 0 and not Aggregation_dir: 121 Aggregation_dir.append(tmp_dir) 122 else : 123 # すでにAggregation_dirに登録されてる分類コードなら:で連結する 124 merge_flg = False 125 for j in range(len(Aggregation_dir)): 126 if Aggregation_dir[j][0] == tmp_dir[0]: 127 if not Aggregation_dir[j][2]: 128 Aggregation_dir[j][2] = tmp_dir[2] 129 merge_flg = True 130 else: 131 Aggregation_dir[j][2] = Aggregation_dir[j][2] + ':' + tmp_dir[2] 132 merge_flg = True 133 if merge_flg == False : 134 Aggregation_dir.append(tmp_dir) 135 print(Aggregation_dir) 136 137 # Aggregation_dirで増えたレコードをもとのpandasに追加 138 139 140 141if __name__ == "__main__": 142 # ログをファイルから読み込み 143 log_parser() 144 145

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

x98000

2020/05/12 07:36

具体的に何が出来ない、何に困っている、を具体的に記載しないと丸投げと見做されますよ
zenji0705

2020/05/13 01:32

コメントありがとうございます。質問内容を更新しました。 現在、for文のループで全レコードを単純にまわして項目チェックしているため、処理速度が遅いロジックになっています。処理速度を改善したいので、いい方法があればアドバイスがほしいです。 大変恐縮ですが、よろしくお願いいたします。
x98000

2020/05/13 05:45

やはり、データイメージ→理想の結果イメージ が理解できません。 ・注文001の 「みかん:りんご」 と 「ピーマン」 をどういうルールで2行に分けるのか(辞書?) ・注文002の レシート をどうやって 領収書 に変えるのか ・注文004の グループが分割されないのはなぜか など、ロジックの前に仕様の把握ができません。 性能改善が目的であれば、問題になるロジックをもっとピンポイントに提示できないでしょうか。その方が回答が付きやすいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問