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

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

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

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

Python

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

Q&A

解決済

1回答

277閲覧

python 足し合わせと平均の求め方

MasaKoba

総合スコア18

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2017/10/16 07:08

###前提・実現したいこと
初めましてMasaKobaと申します。まだプログラミング初心者です。
Pythonの足し合わせのコードについての質問です。
例えば、以下のデータにおいて、(48+29+28+23+25)/5の計算をしたいときどのようなやり方がございますでしょうか。ご教示いただけますと幸いです。

2011/4/1,48
2011/4/2,29
2011/4/3,28
2011/4/4,23
2011/4/5,25

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

エラーメッセージ

###該当のソースコード
import re
import csv
import datetime

compare1 = datetime.date(2011, 4, 1)
compare2 = datetime.date(2011, 4, 6)

with open("moving_train.csv", "r", newline="") as f:
reader = csv.reader(f)
for rows in reader:
time = rows[0]
cols = time.split("/")
a = datetime.date(int(cols[0]), int(cols[1]), int(cols[2]))

# 平均を求める if a >= compare1 and a < compare2: for i in cols[2]:

         print(rows[1])

これより以下がわかりません。。基礎の基礎からしれませんがご教示いただけますとうれしいです。よろしくお願いいたします。

###試したこと
分母については、i[-1:]で5になると思いましたが、i[0]=12345と縦にアウトプットされただけで、i[1]~i[4]まではrange外と出てきました。
分子については、上記のようにcols[2]が1-5のそれぞれのときに、rows[1]のそれぞの値をまず出しましたが、これらをどのように足し合わせていくかがわかりませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答1

0

ベストアンサー

データの読み取りと、それに対する処理は分けた方がよいです。

Python

1import csv 2import datetime 3 4# 辞書にデータを読み取る 5date_dict = {} 6with open("moving_train.csv", "r", newline="") as f: 7 reader = csv.reader(f) 8 for row in reader: 9 date = map(int, row[0].split('/')) 10 date_dict[datetime.date(*date)] = int(row[1]) 11 12# フィルター用の関数 13def is_in_date_range(date): 14 return datetime.date(2011, 4, 1) <= date < datetime.date(2011, 4, 6) 15 16# 上記関数に適合しない要素を取り除く 17date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items())) 18 19"""この時点でのdate_dict (見やすく成形しています) 20{datetime.date(2011, 4, 1): 48, 21 datetime.date(2011, 4, 2): 29, 22 datetime.date(2011, 4, 3): 28, 23 datetime.date(2011, 4, 4): 23, 24 datetime.date(2011, 4, 5): 25} 25""" 26 27total = sum(date_dict.values()) 28average = 1.0 * total / len(date_dict) 29print(total, average) 30 31"""実行結果 32153 30.6 33"""

『試したこと』に関しましては、よく理解できなかったのでスルーします。

コメントを受けて

filterは便利な関数なのですが、慣れるまでは意味が分かりづらいかもしれませんね。
簡単に説明すると、次のようになります。

filterは第一引数に関数を、第二引数にリストを取ります。
リストの要素ひとつひとつを関数に渡し、Falseである要素を取り除く働きをします。
以下、簡単な実験コードです。

Python

1>>> def ret_true(arg): 2... return True 3... 4>>> def ret_false(arg): 5... return False 6... 7>>> def over_3(arg): 8... return arg > 3 9... 10>>> my_list = list(range(10)) 11>>> my_list 12[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 13>>> 14>>> list(filter(ret_true, my_list)) 15[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 16>>> 17>>> list(filter(ret_false, my_list)) 18[] 19>>> 20>>> list(filter(over_3, my_list)) 21[4, 5, 6, 7, 8, 9]

条件に合わない要素を取り除く働きが分かりますでしょうか。
なお上記の解説は、簡潔な一方で若干不正確です。正確な解説はこちら


次に、ラムダ式というものを利用して前述の実験コードを書き直してみます。

Python

1>>> my_list = list(range(10)) 2>>> my_list 3[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 4>>> 5>>> list(filter(lambda arg: True, my_list)) 6[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 7>>> 8>>> list(filter(lambda arg: False, my_list)) 9[] 10>>> 11>>> list(filter(lambda arg: arg > 3, my_list)) 12[4, 5, 6, 7, 8, 9]

このように、いちいち使い捨てる関数を定義しないで用いることが出来ます。
私のコードでは、ラムダ式と関数とを組み合わせる形でフィルタリングを実現しています。

Python

1# フィルター用の関数 2def is_in_date_range(date): 3 return datetime.date(2011, 4, 1) <= date < datetime.date(2011, 4, 6) 4 5# 上記関数に適合しない要素を取り除く 6date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items()))

辞書のアイテム(キーと値)を取り出し、そのキーを関数に与えたときの結果を指標としています。
難しく感じるかもしれませんが、これは慣れもありますので。

結局なにをやっているのか?

Python

1# フィルター用の関数 2def is_in_date_range(date): 3 return datetime.date(2011, 4, 1) <= date < datetime.date(2011, 4, 6) 4 5# 上記関数に適合しない要素を取り除く 6date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items()))

次のように書いても、結果は一緒です。

Python

1for key in date_dict: 2 if datetime.date(2011, 4, 1) <= key < datetime.date(2011, 4, 6): 3 pass 4 else: 5 del date_dict[key]

こっちの書き方でも充分簡潔ですね。最初からこっちを書いた方が良かったかも。


Teratailには、コードを上記のように見やすく表示する機能があります。
編集画面を開き、コードを選択した状態で<code>ボタンを押してください。
特にPythonの場合、インデントが崩れるとコードの意味が変わってしまいます。

投稿2017/10/16 07:42

編集2017/10/16 09:32
LouiS0616

総合スコア35658

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

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

MasaKoba

2017/10/16 08:59

早速ありがとうございます!大変勉強になります。なお、追加で教えていただけないでしょうか。以下は何を意味しているのでしょうか。 # 上記関数に適合しない要素を取り除く date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items()))
LouiS0616

2017/10/16 09:19

回答に追記しましたが、いろいろな知識を用いているので、理解はなかなか大変だと思います。 理解するためには、次の知識が必要です。(左にいくほど基礎的) ・辞書型 ・ラムダ式 ・高階関数 勉強する中で、そのうちわかるという感覚で問題ないかと。
LouiS0616

2017/10/16 09:23 編集

いちおう簡単なバージョンも書いておこうと思います。少々お待ちください。 ※追記しました。
MasaKoba

2017/10/16 11:14

LouiS0616さん、ご丁寧にありがとうございます!すごく勉強になります!今後とも何卒よろしくお願いいたします。また追加で質問させていただきましたので、可能な範囲でご回答いただけますと幸いです。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問