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

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

ただいまの
回答率

90.76%

  • Python

    6914questions

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

  • Python 3.x

    5364questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 398

MasaKoba

score 12

前提・実現したいこと

初めまして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/ツール等のバージョンなど)

より詳細な情報

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

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

import csv
import datetime

# 辞書にデータを読み取る
date_dict = {}
with open("moving_train.csv", "r", newline="") as f:
    reader = csv.reader(f)
    for row in reader:
        date = map(int, row[0].split('/'))
        date_dict[datetime.date(*date)] = int(row[1])

# フィルター用の関数
def is_in_date_range(date):
    return datetime.date(2011, 4, 1) <= date < datetime.date(2011, 4, 6)

# 上記関数に適合しない要素を取り除く
date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items()))

"""この時点でのdate_dict (見やすく成形しています)
{datetime.date(2011, 4, 1): 48,
 datetime.date(2011, 4, 2): 29, 
 datetime.date(2011, 4, 3): 28,
 datetime.date(2011, 4, 4): 23,
 datetime.date(2011, 4, 5): 25}
"""

total = sum(date_dict.values())
average = 1.0 * total / len(date_dict)
print(total, average)

"""実行結果
153 30.6
"""

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

コメントを受けて

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

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

>>> def ret_true(arg):
...     return True
...
>>> def ret_false(arg):
...     return False
...
>>> def over_3(arg):
...     return arg > 3
...
>>> my_list = list(range(10))
>>> my_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
>>> list(filter(ret_true, my_list))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
>>> list(filter(ret_false, my_list))
[]
>>>
>>> list(filter(over_3, my_list))
[4, 5, 6, 7, 8, 9]

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


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

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

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

# フィルター用の関数
def is_in_date_range(date):
    return datetime.date(2011, 4, 1) <= date < datetime.date(2011, 4, 6)

# 上記関数に適合しない要素を取り除く
date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items()))

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

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

# フィルター用の関数
def is_in_date_range(date):
    return datetime.date(2011, 4, 1) <= date < datetime.date(2011, 4, 6)

# 上記関数に適合しない要素を取り除く
date_dict = dict(filter(lambda x: is_in_date_range(x[0]), date_dict.items()))

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

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

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


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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/16 17:59

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

    キャンセル

  • 2017/10/16 18:19

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

    キャンセル

  • 2017/10/16 18:20 編集

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

    キャンセル

  • 2017/10/16 20:14

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

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    6914questions

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

  • Python 3.x

    5364questions

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