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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1810閲覧

空欄の行をはじいて解析する

nomay_c

総合スコア8

Python 3.x

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/08/23 13:26

編集2017/08/23 13:42

###前提・実現したいこと
あるデータの解析をしたいと思っています。
745164EA 80 00 00 00 31 00 32 00 7332CD3F 080159.008 070817 A 08 0 +0050
745164EA 00 00 38 00 00 00 00 3F 7332CD3F 080159.008 070817 A 08 0 +0050
745164EB 00 00 00 23 00 24 00 00 7332CD3F 080159.008 070817 A 08 0 +0050
74C7A363 BF 00 00 00 3F 00 3B 00 74B0457F 080200.000 070817 A 08 0 +0058
データファイルはこのようになっていて、一番左の745164EAの列をrow[0]、行全体をrowとしています。

このデータファイルでは、たまに空欄の(何も書いていない)行やrow[0]がアルファベットの行があるため、その行をはじいて解析をしたいと思っています。

###発生している問題・エラーメッセージ

list index out of range
空欄の行をはじくことができません。空欄の行にぶつかると、解析がストップしてエラーが出てしまいます。

###該当のソースコード

num

1min = 1 #読み取り始める行数 2max = 1000000 #読み取り終わる行数 3with open(filename, 'r') as f: 4 reader = csv.reader(f, delimiter=' ') 5 for row in reader: 6 if num >= max: #numがmax以上だったらループから外れる 7 break 8 elif num >= min: #numがmin以上だったら実行する 9 print (row[0]) 10 11 if row[0] =="ST" or row[0] =="BA" or row[0] == "DS": 12 continue 13 elif len(row) != 16: 14 continue 15 else: 16 for i in range(0,9): 17 data1[i].append(int(row[i],16)) 18 data1[10].append(row[10]) 19 num += 1 20コード

###試したこと
len(row) != 16:となっているところを、row[0] == ""としてみましたが、それもできませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
python Sublime Text 3 コマンドプロンプト

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

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

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

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

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

nomay_c

2017/08/23 13:39

わかりました。ありがとうございます。
guest

回答1

0

ベストアンサー

IndexError が起きているのは、csv.reader でデータを読み込んだ row リストではなく,
data1 リストのようです。具体的には data1[i].append(int(row[i],16)) の部分で起きています。

もし data1 の中身を初期化していないならば、data1[0], data1[1] ... という要素は存在しないため、存在しないものに append() することはできません。

data1 リストに各列のデータを格納したリストを前詰めで入れていくなら、例えば次のようなコードにします。各列のデータを入れた row_list リストを data1 リストの末端に追加しています。つまりリストの中にリストを入れています。

python

1num = 0 2data1 = [] 3for row in csv.reader(open(filename, 'r'), delimiter=' '): 4 num += 1 5 if num >= max: # numがmax以上だったらループから外れる 6 break 7 elif num < min: # numがmin以上だったら実行する 8 continue 9 10 if row[0] in ['ST', 'BA', 'DS']: 11 continue 12 elif len(row) != 16: 13 continue 14 else: 15 row_list = [] 16 for i in range(0, 9): 17 row_list.append(int(row[i], 16)) 18 row_list.append(row[10]) 19 data1.append(row_list)
# 結果 [[1951491306, 128, 0, 0, 0, 49, 0, 50, 0, '080159.008'], [1951491306, 0, 0, 56, 0, 0, 0, 0, 63, '080159.008'], [1951491307, 0, 0, 0, 35, 0, 36, 0, 0, '080159.008'], [1959240547, 191, 0, 0, 0, 63, 0, 59, 0, '080200.000']]

もし data1 をキーを前詰め(連番)ではなく元データの行番号にしたい場合は、リストではなくOrderedDictを使うとよいでしょう。

python

1from collections import OrderedDict 2 3num = 0 4data1 = OrderedDict() 5for row in csv.reader(open(filename, 'r'), delimiter=' '): 6 num += 1 7 if num >= max: # numがmax以上だったらループから抜ける 8 break 9 elif num < min: # numがmin未満だったらスキップ 10 continue 11 12 if row[0] in ['ST', 'BA', 'DS']: 13 continue 14 elif len(row) != 16: 15 continue 16 else: 17 row_list = [] 18 for i in range(0, 9): 19 row_list.append(int(row[i], 16)) 20 row_list.append(row[10]) 21 data1[num] = row_list
# 結果 OrderedDict([(1, [1951491306, 128, 0, 0, 0, 49, 0, 50, 0, '080159.008']), (3, [1951491306, 0, 0, 56, 0, 0, 0, 0, 63, '080159.008']), (5, [1951491307, 0, 0, 0, 35, 0, 36, 0, 0, '080159.008']), (6, [1959240547, 191, 0, 0, 0, 63, 0, 59, 0, '080200.000'])])

なお data1 にデータを追加するとき、Python の内包表記というテクニックを使うと、ちょっとかっこよく書けます。

python

1# before 2row_list = [] 3for i in range(0, 9): 4 row_list.append(int(row[i], 16)) 5row_list.append(row[10]) 6data1.append(row_list) 7 8# after 9data1.append([int(row[i], 16) for i in range(0, 9)] + [row[10]])

ちなみに num をループの最後にカウントアップしていますが、continue したときにカウントアップしないため、目的のデータを1000000個取り込んだら終了という意味になります。もし元データの1000000行目で終了としたいのなら、上記に示したサンプルコードのように最初に num += 1 してください。

投稿2017/08/23 14:09

編集2017/08/23 14:30
miyahan

総合スコア3095

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

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

nomay_c

2017/08/23 14:51

if row[0] == "ST" or row[0] == "BA" or row[0] == "DS": IndexError: list index out of range と出てきてしまうのですが、わかりますか…?
miyahan

2017/08/23 15:00

元データに空行があるんでしょうか? それなら、if 文の順番を ``` if len(row) != 16: continue elif row[0] == "ST" or row[0] == "BA" or row[0] == "DS": continue ``` と入れ替えて、最初に空行を continue するように改良してください。
nomay_c

2017/08/23 15:15

できました!丁寧にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問