🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1168閲覧

配列から特定の曜日と時間帯のデータを抽出し,計算する

TKWTsan

総合スコア8

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2019/10/24 13:00

編集2019/10/24 13:02

プログラミング初心者です.
現在,pythonを用いてcsv形式のデータの分析を行っております.
前提として,csv,numpy,pandasなどのモジュールを使用しないプログラムを組んでおります.

ある要素を持つデータをすべて抽出した後,特定の曜日(平日)と,
特定の時間帯(8:00~18:00)のみのデータを抜き出し,その中のある要素の平均値を算出するプログラムを自分なりに組んでみたのですが,以下のように長くなってしまいました.
elif部分の重複をなくす,あるいはほかにプログラムを簡潔に示す方法があれば
ご指摘よろしくお願いします.

読み込むcsvファイルは2018/09/01(Sat)から2018/09/30(Sun)です.

python

1import datetime 2 3filepath = 'aaa.csv' 4 5with open(filepath,encoding='shift-jis') as f: 6 7 data2 = [] 8 for line in f: 9 line = line.replace('\n','') 10 data = line.split(',') 11 data2.append(data) 12 13 data3=[] 14 for i in data2: 15 if i[2] =='1': 16 data3.append(i) 17 for i in data3: 18 tmdata=(datetime.datetime.strptime(i[0],'%Y/%m/%d %H:%M')) 19 i[0]=tmdata 20sum=0 21n=0 22a=1 23b=0 24 25for i in data3: 26 if i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*b and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*b\ 27 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 28 sum = sum + int(i[7]) 29 n += 1 30 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*a and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*a\ 31 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 32 sum = sum + int(i[7]) 33 a += 1 34 b += 1 35 n += 1 36 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+1) and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+1)\ 37 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 38 sum = sum + int(i[7]) 39 a += 1 40 b += 1 41 n += 1 42 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+2) and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+2)\ 43 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 44 sum = sum + int(i[7]) 45 a += 1 46 b += 1 47 n += 1 48 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+3) and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+3)\ 49 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 50 sum = sum + int(i[7]) 51 a += 1 52 b += 1 53 n += 1 54 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+4) and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+4)\ 55 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 56 sum = sum + int(i[7]) 57 a += 1 58 b += 1 59 n += 1 60 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+5) and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+5)\ 61 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 62 sum = sum + int(i[7]) 63 a += 1 64 b += 1 65 n += 1 66 elif i[0] < datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+6) and i[0] >= datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M')+datetime.timedelta(days=1)*(a+6)\ 67 and not i[0].strftime('%a') == 'Sat' and not i[0].strftime('%a') == 'Sun': 68 sum = sum + int(i[7]) 69 a += 1 70 b += 1 71 n += 1 72 73print(sum/n) 74

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

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

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

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

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

Akihito_Jv

2019/10/24 14:02

失礼します。 csvファイルのデータをご提示いただけませんでしょうか。
TKWTsan

2019/10/24 14:29

ご質問ありがとうございます. http://public-data.jartic-raws.durasite.net/opendata.html このサイトの「一般道路の「断面交通量情報」 (2019年8月分)」がほぼ同じ形式のデータになります. プログラムでは2018年9月ですが,用意できたデータは2019年8月のみでした. よろしくお願いします.
guest

回答2

0

datatime.weekday()で曜日が取得できるのとdatetime.hourでhourの部分が取得できます。
これを活用して受け入れる曜日、時間帯をテーブル化し、それに基づいてデータをフィルタします。

Python

1import datetime 2 3filepath = 'aaa.csv' 4 5with open(filepath,encoding='shift-jis') as f: 6 7 data2 = [] 8 for line in f: 9 line = line.replace('\n','') 10 data = line.split(',') 11 data2.append(data) 12 13 data3=[] 14 for i in data2: 15 if i[2] =='1': 16 data3.append(i) 17 for i in data3: 18 tmdata=(datetime.datetime.strptime(i[0],'%Y/%m/%d %H:%M')) 19 i[0]=tmdata 20 21accept_weekday = [ 22 True, # 月曜日 23 True, # 火曜日 24 True, # 水曜日 25 True, # 木曜日 26 True, # 金曜日 27 False, # 土曜日 28 False # 日曜日 29] 30 31accept_hour = [ 32# 0 1 2 3 4 5 6 7 8 9 10 11 33 False, False, False, False, False, False, False, False, True , True , True , True , 34# 12 13 14 15 16 17 18 19 20 21 23 23 35 True , True , True , True , True , True , False, False, False, False, False, False, 36] 37 38 39sum = 0 40n = 0 41 42for i in data3: 43 44 # 曜日判定 45 if accept_weekday[i[0].weekday()] == False: 46 continue 47 48 # 時間帯判定 49 if accept_hour[i[0].hour] == False: 50 continue 51 52 sum = sum + int(i[7]) 53 n = n + 1 54 55print(sum/n)

投稿2019/10/24 17:11

nomuken

総合スコア1627

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

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

TKWTsan

2019/10/25 00:50

ご指摘ありがとうございます. 参考にさせていただきます.
guest

0

ベストアンサー

失礼します。
ご提示いただいたサイトから、
北海道函館市のデータを取得しました。
取得したデータの一部が以下となります。

aaa.csv

12019/08/01 00:00,3002,1,110,36,4,27,25,8,,201800 22019/08/17 17:55,3002,11,115,47,3,11,31,8,,201800 32019/08/17 18:50,3002,20,105,37,13,35,15,,,201800 42019/08/30 08:15,3002,13,120,29,7,34,23,7,,201800

そして、記載されていたコードを書き直したのが以下となります。

書き直したポイントとして、

  1. 同じ条件で指定されているデータを定数化した
  2. 処理を順番に分けて処理させた

となります。

私自身まだまだ未熟者でございますので、
実際には、もっといいコードが存在すると思います。
Pythonには、リスト内包表記というものがありますので、
そちらで記載することも可能かと思いますが、
条件が複雑な場合は、単純に記載した方が、冗長にはなってしまいますが、
可読性の高いコードになると思います。

今回書き直したことで、小数点の計算のズレが生じる可能性があり、
リファクタリングが完全に成功しているわけではありませんので、
ご了承ください。

python

1import datetime 2 3filepath = 'abc.csv' 4# 定数 5TIME18 = datetime.datetime.strptime('2018/09/01 18:00','%Y/%m/%d %H:%M').time() 6TIME8 = datetime.datetime.strptime('2018/09/01 8:00','%Y/%m/%d %H:%M').time() 7 8with open(filepath,encoding='shift-jis') as f: 9 10 data2 = [] 11 for line in f: 12 line = line.replace('\n','') 13 data = line.split(',') 14 data2.append(data) 15 16 data3=[] 17 for i in data2: 18 if i[2] == "1": 19 data3.append(i) 20 21 for i in data3: 22 tmdata=(datetime.datetime.strptime(i[0],'%Y/%m/%d %H:%M')) 23 i[0]=tmdata 24sum=0 25 26# 平日(土,日を除いたデータ)を格納するリストを宣言する 27weekdays = [] 28# データを回して、平日だけを格納する 29for weekday in data3: 30 if not weekday[0].strftime('%a') == 'Sat' and not weekday[0].strftime('%a') == 'Sun': 31 weekdays.append(weekday) 32 33# 特定の時間(8:00~18:00)のデータを格納するリストを宣言する 34specifiedDate = [] 35# データを回して、特定の時間だけのデータを格納する 36for Specified_time in weekdays: 37 if TIME8 <= Specified_time[0].time() and Specified_time[0].time() <= TIME18: 38 specifiedDate.append(Specified_time) 39 40# 残りのデータは、平日8:00から18:00までのデータになっているので、その中の要素を計算する。 41for i in specifiedDate: 42 sum = sum + int(i[7]) 43 44print(sum/len(specifiedDate))

投稿2019/10/24 16:28

Akihito_Jv

総合スコア64

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

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

TKWTsan

2019/10/25 00:46

ご指摘の通り,特定の曜日のリストを新しく作成して、計算したほうが分かりやすいですね. ありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問