• 締切済み

Python について質問です

私はPythonの初心者です。 今Python でCSVのファイルを読んで数値だけ(数値以外に文字列や空白などがあります)を計算処理出来なくて困っています。教えて頂けませんか? 質問は、BB.csvというファイルの数値だけの合計と平均を計算したいです。 私のコードは以下です。 # coding: utf-8 import csv import re import string DATAFILE = 'BB.csv' class UnicodeDictReader(csv.DictReader): def __init__(self, f, fieldnames=None): csv.DictReader.__init__( self, f, fieldnames) def main(): total = 0 all_sum = 0 line_num = 0 with open(DATAFILE) as csvfile: reader = UnicodeDictReader(csvfile) for record in reader: # 値を数値で取得 A = int(record['38186']) B = int(record['38181']) C = int(record['38143']) item_total = A + B + C total = item_total all_sum += item_total line_num += 1 average = all_sum / reader.line_num print(" %d + %d + %d = %d " % ( A, B, C, total)) print(u"合計 %d " % all_sum) print(u"平均 %d " % average) if __name__ == '__main__': main() BB.csvは以下です、 38186,38181,38143 1,1,4 1,1,4 ,, ,, 2020,2020,2020 1412,1412,1412 625,625,625 75,75,75 75,75,75 75,75,75 75,75,75 4,4,4 4,4,4 4,4,4 7828,7828,7828 X,, 0,0,0 0,0,0 ○,, 0,0,0 0,0,0 0,0,0 ,,AAA 0,0,0 0,0,0 0,0,0 ,BBB, 0,0,0 0,0,0 0,0,0 ,, 0,0,0 ,, 0,0,0 0,0,0 ,, 0,0,0 0,0,0 750,750,750 400,400,400 400,400,400 ,, 0,0,0 0,0,0 0,0,0 ,, 0,0,0 0,0,0 0,0,0 0,0,0 0,0,0 0,0,0 0,0,0 6,6,6 6,6,6 18,18,18 18,18,18 18,18,18 18,18,18 18,18,18 16,16,16 16,16,16 6,6,6 6,6,6 18,18,18 18,18,18 18,18,18 18,18,18 18,18,18 11,11,11 11,11,11 11,11,11 3,3,3 3,3,3 3,3,3 3,3,3 4,4,4 4,4,4 3,3,3 3,3,3 16,16,16 16,16,16 16,16,16 14,8,11 8,14,11 8,14,11 8,14,11 8,14,11 8,14,11 8,14,11 8,14,11 8,14,11 15,15,15

みんなの回答

回答No.2

どの言語でもそうですが、ちゃんとライブラリーのマニュアルを読んだほうが早いですよ。 http://docs.python.jp/2/library/csv.html > BB.csvファイルの中に数値意外にBBB,X,,,などの文字列あります。私は数値だけを計算して合計と平均を出したいです。そのBBB,x,,,などをどのように処理して数値計算をできますか?今はそのBBB,x,,,などの文字列が邪魔しています。 正規表現で数値とマッチして外れた行が出現したら無視するか、ValueErrorをちゃんと処理するかでしょうね。 > とありますが、 「38186,38181,38143」 の行は「見出し」の行なのでしょうか? 「38186,38181,38143」も計算したいです。 http://docs.python.jp/2/library/csv.html#csv.DictReader | fieldnames パラメタが無い場合には、 csvfile の最初の行の値がフィールド名として利用されます。 とちゃんと書いてありますよね。 そういう見方が必要ないなら、csv.DictReaderではなく単純にcsv.readerを使えばよいのではないでしょうか? http://docs.python.jp/2/library/csv.html#csv.reader > 小数点以下を計算したいです。 それならちゃんと浮動小数点型を使いましょう。int(...)だと整数型になるので、小数点以下は自動的に切り捨てになると思います。 http://docs.python.jp/2/library/stdtypes.html#int-float-long-complex >>> average = all_sum / reader.line_num としながら、 > line_num += 1 としていて、正直何をしたいのかわかりませんが、平均というなら、行数ではなく数値であった要素の個数で割らないと意味ないのでは? というわけで、元のプログラムからちょっと変えて書いてみました。 # coding: utf-8 import csv import re import string DATAFILE = 'BB.csv' def main(): total = 0 all_sum = 0 num_items = 0 with open(DATAFILE) as csvfile: reader = csv.reader(csvfile) for record in reader: # 値を数値で取得 try: A = int(record[0]) B = int(record[1]) C = int(record[2]) except (IndexError, ValueError): continue item_total = A + B + C all_sum += item_total num_items += 1 print(" %d + %d + %d = %d " % ( A, B, C, item_total)) average = float(all_sum) / float(num_items) print("sum= %d " % all_sum) print("num= %d " % num_items) print("ave= %.2f " % average) if __name__ == '__main__': main() なお、このプログラムでは数値でないものがあったらその行がなかったものだとして動作します。つまり、合計値にはその行そのものが加えられませんし、平均を計算するときの分母としてもカウントされません。 特に必要ではないcsv.DictReaderでなくcsv.readerを使って書き直しました。 totalという不要な変数を消しました。 適宜自分で理解して改行を入れてください。 ...余談ですが、NUMというと、普通"the number of"の略ということで要素数を示すと思います。all_sumを出すならせめてsumやtotalと言う方が自然だと思います。

noname#187756
質問者

補足

ありがとうございます!大変勉強になりました。 違う方向での質問です。 元BB.csvファイルをBB.txtファイルにして、行ごと(3行、縦に)の合計と平均を計算したいです、教えていただけませんか? 以下かpyファイルです。 #encoding=utf-8 import csv import sys import string import re with open('BB.txt') as f: sum = [] Avg = 0 prog = re.compile(r'[0-9]+') for line in f.readlines()[1:]: prog.match(line['01']) prog.match(line['02']) prog.match(line['03']) row = [int(f) for f in line.strip().split(',')] sum = row if not sum else\ [sum[i] + row[i] for i in xrange(len(row))] Avg = sum/ print ("SUM ", sum) print ("AVGi::", Avg) BB.txtは以下です 38186,38181,38143 1,1,4 1,1,4 ,, ,, 2020,2020,2020 1010,1010,1010 1412,1412,1412 50,55,75 4,4,4 625,625,625 625,625,625 75,75,75 650,650,650 250,250,250 4,4,4 7828,7828,7828 X,, 0,0,0 0,0,0 ○,, 0,0,0 0,0,0 0,0,0 ,,AAA 0,0,0 0,0,0 0,0,0 ,BBB, 0,0,0 0,0,0 0,0,0

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

ここのシステムは、空白がまとめられてしまう、というPythonにとっては致命的な特徴があります。 なので、インデント間違いによる不具合は指摘することができません。 あなたの言う「計算処理出来なくて」とは、具体的にどのような状況なのでしょうか? それにより、答えも変わってきます。 csv.DictReader は、指定がなければ、1行目を「見出し」と解釈し、2行目以降のデータを、「見出し」を使った辞書型として読みだせるものです。 http://docs.python.jp/2/library/csv.html#csv.DictReader > A = int(record['38186']) > B = int(record['38181']) > C = int(record['38143']) とありますが、 「38186,38181,38143」 の行は「見出し」の行なのでしょうか? それとも、これも計算したい数値なのでしょうか? 計算したい数値なら、DictReaderでは不向きです。 > 数値だけ(数値以外に文字列や空白などがあります) とありますが、それを判定している部分があまりせん。 そのため、4行目の「,,」で record['38186']='' となり、 int('')となって、エラーになります。 > average = all_sum / reader.line_num 整数/整数は整数になります。小数点以下は出ません。 どこまで求めるおつもりでしょうか? reader.line_num は、読み込んだ行数です。 http://docs.python.jp/2/library/csv.html#csv.csvreader.line_num 今回の場合、数値でない行も含まれます。 平均を求める母数にしたいのは、数値の無い行も含めた行数なのでしょうか? それなら、 readerのline_numになります。 数値のある行数だけでしょうか? その場合は、おそらく line_num += 1 としている変数line_numが使えると思います。(字下げが不明なので、期待する値になっているか定かではありませんが) あるいは、行数ではなく、数値の数なのでしょうか?

noname#187756
質問者

補足

ご指摘ありがとうございます。 >>あなたの言う「計算処理出来なくて」とは、具体的にどのような状況なのでしょうか? それにより、答えも変わってきます。 BB.csvファイルの中に数値意外にBBB,X,,,などの文字列あります。私は数値だけを計算して合計と平均を出したいです。そのBBB,x,,,などをどのように処理して数値計算をできますか?今はそのBBB,x,,,などの文字列が邪魔しています。 簡単にいえば、BB.csvファイルを使って合計と平均を出したいです。 >>>> A = int(record['38186']) > >>B = int(record['38181']) > >>C = int(record['38143']) とありますが、 「38186,38181,38143」 の行は「見出し」の行なのでしょうか? 「38186,38181,38143」も計算したいです。 >>> 数値だけ(数値以外に文字列や空白などがあります) >>>とありますが、それを判定している部分があまりせん。 はい、その判定するのをできませんでした。 これを教えて頂きたいです。 >>> average = all_sum / reader.line_num 小数点以下を計算したいです。 >>>あるいは、行数ではなく、数値の数なのでしょうか? 行数を示しているつもりです。 nn.py import csv import re import string DATAFILE = 'Book1.csv' class UnicodeDictReader(csv.DictReader): def __init__(self, f, fieldnames=None): csv.DictReader.__init__( self, f, fieldnames) def main(): total = 0 all_sum = 0 line_num = 0 with open(DATAFILE) as csvfile: reader = UnicodeDictReader(csvfile) for record in reader: A = int(record['38186']) B = int(record['38181']) C = int(record['38143']) item_total = A + B + C total = item_total all_sum += item_total line_num += 1 average = all_sum / reader.line_num print(" %d + %d + %d = %d " % ( A, B, C, total)) print("NUM %d " % all_sum) print("Avg %d " % average) if __name__ == '__main__': main() 今上記のコードを実行すると下記のような結果が出ます。 1 + 1 + 4 = 6 1 + 1 + 4 = 6 Traceback (most recent call last): File "nn.py", line 55, in <module> main() File "nn.py", line 41, in main A = int(record['38186']) ValueError: invalid literal for int() with base 10: '' hasuchoro-no-iMac:csv hasuchoro$ すみませんがご授教くださいませ!

関連するQ&A