• 締切済み

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

noname#187756
noname#187756

みんなの回答

回答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

  • c言語の関数について

    .#include<stdio.h> int input_number(void); int main(void) { int num; int total = 0; while(){ num = input_number(); if(num == 0){ break; } total = total + input_number(); } printf("¥n合計値は%dです¥n", total); return 0; } int input_number(void) { int num; printf("数値を入力してください: "); scanf("%d", &num); return num; } 個人でcを勉強しております。 このプログラムで間違っているところを教えていただけませんでしょうか? 苦戦して困っております。できれば勉強法も教えてていただきたいです。 どうか宜しくお願いします。

  • csvファイルの実績データをC言語で解析するのですが...

    C言語を学び始めたばかりなのに、csvファイルの実績データでフィールドが15あり、レコード数が1000000近くあるファイルの15番目のフィールドを足し合わせて、出力するということをやっているのですが、まだまだわからないことだらけです。 1レコード目がカラム名なので2レコード目から足し合わせるんですがそこのところもよくわからずじまいで... 一応、書いたプログラムが #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char buffer[50],*p; int cnt, num, sum; fp = fopen("j0.csv","r"); if(fp == NULL){ printf("ファイルが開けませんでした。\n"); exit(-1); } while(fgets(buffer,fp) != NULL){ p = strtok(buffer,","); cnt = 1; while(p!=NULL){ num = atoi(p); printf("%d:%d,",cnt,num); p = strtok(NULL,","); cnt++; if(cnt==15) sum=sum+num } printf("\b\b \n"); } printf(%d \n",num); fclose(fp); return(0); } と書いたんですが、ぜんぜんな状態です。誰かご教授願えませんか?

  • 関数についての質問です。

    c言語を勉強しています。関数で戻り値がありますが、関数の処理の仕組みが理解できません。本等で勉強し僕の考え方が間違っていたら教えてください。 お願いいたします。 #include <stdio.h> int buy(int x,int y ) { int z; //1 printf("%d万円と%d万円の車を買いました。");//2 z=x+y; //3 return z; //4 } int main(void) { int num1,num2,num;//5 printf("いくらの車をかいますか?\n");//6 scanf("%d",&num1);//7 printf("いくらの車をかいますか?\n");//8 scanf("%d",&num2);//9 sum=buy(num1,num2);//10 printf("合計で%d万円です。\n",sum);//11 return 0;//12 } まず最初に 整数型、int num1,num2,numを読みます。 次に//7と//8で数値を入力します。 そして//10で値を格納し int buy( int x,int y)に値をわたします。 ※正確には関数buyに渡す。 そして計算をし計算結果 zをreturn で int buy(int x,int y )の buyに値を渡します。 そのあと呼び出し元の//10のbuyに値をかえします。 そしてプログラムが終了します。 間違っていたら教えてください。

  • ループ

    #include<stdio.h> int main(void) { int i=1,sum=0; int num=1; while(num>0) { printf("整数を入力してください。(マイナスの値で終了)\n"); scanf("%d",&num); printf("%dが入力されました。(%d番目の繰り返しです)\n",num,i); sum+=i; printf("1から%dまでをたすと%dです。\n",i,sum); i++; } printf("繰り返しが終わりました。\n"); printf("加算値は%dです。\n",sum); printf("%d回繰り返しました。\n",i); return 0; } このプログラムで101以上の数値は加算しないようにするにはどうすればいいですか。

  • C言語初心者です。次の問題で質問です。

    (問題) 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の整数を全て加えた値表示するプログラムを作成せよ。 (自分の解答) #include <stdio.h> int main(void) { int num1,num2; int sum=0; do { printf("整数1>整数2となる整数をそれぞれ入力してください\n"); printf("整数1:"); scanf("%d",&num1); printf("整数2:"); scanf("%d",&num2); if (num1 < num2) printf("整数1>整数2としてください\n"); } while (num1 < num2); printf("%d以上%d以下の全整数の和は",num2,num1); for (num2;num2 <= num1;num2++) { sum=sum+num2; } printf("%dです。",sum); return 0; } これでも一応正しく実行されるのですが、ごちゃごちゃしてるので簡潔に書けないでしょうか? 回答お願いします。

  • 文字列をint型へ変換するには?

    c言語初心者です。 こちらのプログラムだとうまく表示されません何故でしょう? わかる方是非教えていただきたいと思います。 #include<stdio.h> #include <stdlib.h> int main() { int  num ;     char sum1[4]; printf("数字 str1 =>"); scanf("%d",&num); num= atoi(sum11); printf("sum1= [%d]\n",num); } コマンドに数字を入力したあとintに変換してnumに表示させたいのですが、、、、

  • c言語で平均をだす

    #include<stdio.h> int main(void) { int num; int sum; printf("テストの点数を入力してください。\n"); do{ scanf("%d",&num); sum+=num; }while(num); printf("テストの合計点は%dです\n",sum); return 0; } テストの平均点をだすプログラムを作りたいのですが、合計を出すまではわかったのですが、ここから、平均を出すようにするにはどうすればよいですか。

  • コンパイルエラー

    コンパイルしても、12行目(printf("%d番目の整数を入力してください。"i+1);が、関数呼び出しに)がないとでます。でもどこが間違っているか分かりません。 教えてください。お願いします。 #include <stdio.h> int main(void) { int num; int sum=0; int i; for(i=0; i<10; i++){ printf("%d番目の整数を入力してください。"i+1); scanf("%d", &num); sum+=num; } printf("合計は、%dです。\n", sum); return(0); }

  • VBAからPythonを動かしたいのですが…

    いつもお世話になっております。 icevainと申します。 python超初心者です。 【質問】 『VBAでPythonを動かす』という興味のあるサイトを見つけました。 https://qiita.com/O_LUPAN/items/1ceb5c950ff40f3558ab サイトのpythonコード #ここから import sys def sum(suji1, suji2): return suji1 + suji2 if __name__ == "__main__": argv = sys.argv suji1 = str(argv[1]) suji2 = str(argv[2]) total = sum(suji1, suji2) print(total) #ここまで サイトのpythonコードを無理やり変更して、 #ここから import sys def sum(suji1, suji2): rst="OK" return rst if __name__ == "__main__": argv = sys.argv suji1 = str(argv[1]) suji2 = str(argv[2]) total = sum(suji1, suji2) print(total) #ここまで OKがかえってくると思ったのですが、 0がかえってきてしまいます。 OKをかえすにはどうすればよいのかわかりません。 お分かりの方おりましたらご協力お願い致します。

  • 1000000レコードもあるcsvファイルの実績データをC言語で計算しているのですが...

    C言語を学び始めたばかりなのに、csvファイルの実績データでフィールドが15あり、レコード数が1000000近くあるファイルの15番目のフィールドを足し合わせて、出力するということをやっているのですが、まだまだわからないことだらけです。 一応、書いたプログラムが #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE *fp; char buffer[50],*p; int cnt, num, sum; fp = fopen("j0.csv","r"); if(fp == NULL){ printf("ファイルが開けませんでした。\n"); exit(-1); } while(fgets(buffer,fp) != NULL){ p = strtok(buffer,","); cnt = 1; while(p!=NULL){ num = atoi(p); printf("%d:%d,",cnt,num); p = strtok(NULL,","); cnt++; if(cnt==15) sum=sum+num } printf("\b\b \n"); } printf(%d \n",num); fclose(fp); return(0); } と書いたんですが、ぜんぜんな状態です。誰かご教授願えませんか?

専門家に質問してみよう