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

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

新規登録して質問してみよう
ただいま回答率
85.35%
CSV

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

Python 3.x

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Python

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

Q&A

1回答

2356閲覧

【Python3】csvファイル 売上データの集計・書き出しについて

退会済みユーザー

退会済みユーザー

総合スコア0

CSV

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

Python 3.x

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Python

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

0グッド

0クリップ

投稿2021/05/13 01:46

編集2021/05/13 02:36

解決したいこと

Python初学者ですが、学習のために既存プログラムの改修を行いたいと考えております。
行いたい内容は、複数のcsvファイルを読み込み、データを整理した後、一つのファイルに書き出しです。
*ページ下部に現状や問題点など記載しております。

ファイルは下記になります。

商品のマスターデータ →/input/items.csv 商品の売上データ(日毎に別ファイル) →/input/sales_raw_20161030.csv /input/sales_raw_20161101.csv ... /input/sales_raw_20161106.csv 書き出し後の売上データ →/output/sales.csv

商品マスターデータ(items.csv)の中身は下記になります。

商品ID、商品名、商品価格

商品の売上データ(sales_raw_YYYYmmdd.csv)の中身は下記になります。

購入ID、ユーザーID、商品ID、個数、販売日時

書き出し後のデータ(sales.csv)は下記になります。

購入ID、ユーザーID、商品ID、商品名、商品価格、個数、販売日時

*商品の売上データの商品IDと商品マスターデータの商品IDを紐付け、紐付く商品名と商品価格を出力させます。

既存のプログラム

py

1import os 2 3def main(): 4 with open('output/sales.csv', mode='w', encoding='utf-8') as sales_f: 5 for name in os.listdir('input/'): 6 if name.startswith('sales_raw_') and name.endswith('.csv') \ 7 and "201611" in name: 8 with open(os.path.join('input/', name), encoding='utf-8') as f: 9 for row in f: 10 data = row.rstrip().split(',') 11 12 with open('input/items.csv', encoding='utf-8') as items_f: 13 for row in items_f: 14 data2 = row.rstrip().split(',') 15 if data2[0] == data[2]: 16 sales_f.write( 17 ','.join(( 18 data[0], 19 data[1], 20 data[2], 21 data2[1], 22 data2[2], 23 data[3], 24 data[4], 25 )) + '\n' 26 ) 27 28 29if __name__ == "__main__": 30 main()

改修途中のプログラム

py

1import os 2import re 3 4def main(): 5 # 商品マスターデータの読み込み処理 6 items = {} 7 with open('input/items.csv', encoding='utf-8') as f: 8 for row in f: 9 item_id, name, price = row.rstrip().split(',') 10 items[item_id] = { 11 'name': name, 12 'price': price 13 } 14 15 # 売上生データの読み込み処理 16 sales = [] 17 for filename in os.listdir('input/'): 18 if filename.startswith('sales_raw_') and filename.endswith('.csv') \ 19 and "201611" in filename: 20 with open(os.path.join('input/', filename), encoding='utf-8') as f: 21 for row in f: 22 data = row.rstrip().split(',') 23 item_id = data[2] 24 if item_id in items: 25 sales.append({ 26 'purchase_id': data[0], 27 'user_id': data[1], 28 'item_id': data[2], 29 'name': items[item_id]['name'], 30 'price': items[item_id]['price'], 31 'volume': data[3], 32 'sold_at': data[4] 33 }) 34 35 # まとめた売上データを書き出し 36 columns = ['purchase_id', 'user_id', 'item_id', 37 'name', 'price', 'volume', 'sold_at'] 38 with open('output/sales.csv', mode='w', encoding='utf-8') as f: 39 for row in sales: 40 row_str = ','.join(str(row[column]) for column in columns) 41 f.write(row_str + '\n') 42 43if __name__ == "__main__": 44 main()

自分で試したこと

今回行いたい内容としましたは、下記になります。
・複雑な文字列の判定に正規表現を使う
・現状の売上生データを読み込む処理では「売上生データのファイル名はどんな名前か」が分かりにくい。
そこで「売上生データのファイル名」にマッチする正規表現を書くことでプログラムを書いてわかりやすくする

Pythonの正規表現を使用するのが初めてで、正規表現モジュールの使い方など調べてみたのですが、どこのコードで正規表現を使うと良いのかが分からず詰まっている状況になります。

その他に何か必要な情報などありましたら、提示いたします。
長くなってしまい、大変恐縮ではございますが、ご教授頂けますと幸いです。
よろしくお願いいたします。

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

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

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

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

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

ppaul

2021/05/13 02:28

処理自体は、globとpandasを使えば10行ぐらいで書けると思いますが、目的は正規表現の学習なのですね。
退会済みユーザー

退会済みユーザー

2021/05/13 02:37 編集

ppaul様 コメントありがとうございます! はい、仰る通りです。 正規表現に辿り着く前に、処理の分離や変数名、辞書を使い一目で理解できるコードになるように改修を行いました。 コンパクトでスタイリッシュに仕上げるというよりは、一つ一つのコードを理解して改修したいというのが目的になります。 念のためですが、既存プログラムを記載いたしました。 よろしくお願いいたします!
guest

回答1

0

プログラミングの勉強ということであれば、まず全体構造を見直しましょう。
機能やアルゴリズムを変更するとき構造が悪いとぐちゃぐちゃになります。
多少手を加えたものを参考として載せておきます。勉強になるようにあえて複数のバグを残した状態にしてあります。
変更箇所は、機能の分離、条件等をコードから除外、コメントのdocstring化です。

python

1import os 2import re 3 4def master_to_itemdict(master_file): 5 '''商品マスターデータの読み込みと辞書変換''' 6 items = {} 7 with open('input/items.csv', encoding='utf-8') as f: 8 for row in f: 9 item_id, name, price = row.rstrip().split(',') 10 items[item_id] = { 11 'name': name, 12 'price': price 13 } 14 15 16def read_one_sales_file(sales_file, items): 17 '''売上生データ1ファイルの読み込みと辞書変換''' 18 sales = [] 19 with open(sales_file, encoding='utf-8') as f: 20 for row in f: 21 data = row.rstrip().split(',') 22 item_id = data[2] 23 if item_id in items: 24 sales.append({ 25 'purchase_id': data[0], 26 'user_id': data[1], 27 'item_id': data[2], 28 'name': items[item_id]['name'], 29 'price': items[item_id]['price'], 30 'volume': data[3], 31 'sold_at': data[4] 32 }) 33 34def read_sales_files(sales_file_list, items): 35 '''売上生データ複数ファイルの読み込みと辞書変換''' 36 return sum([read_one_sales_file(file, items] for file in sales_file_list], []) 37 38 39def make_sales_files(dir, pattern_s, pattern_e, pattern_year): 40 '''売上生データ複数ファイルのリスト作成''' 41 sales_file_list = [] 42 for filename in os.listdir(dir,pattern_s, pattern_e, pattern_year): 43 if filename.startswith(pattern) and filename.endswith(pattern_e) \ 44 and pattern_year in filename: 45 sales_file_list.append(os.path.join(dir, filename) 46 47def write_total_sales(sales, output_file) 48 '''まとめた売上データを書き出し''' 49 columns = ['purchase_id', 'user_id', 'item_id', 50 'name', 'price', 'volume', 'sold_at'] 51 with open('output/sales.csv', mode='w', encoding='utf-8') as f: 52 for row in sales: 53 row_str = ','.join(str(row[column]) for column in columns) 54 f.write(row_str + '\n') 55 56if __name__ == "__main__": 57 data_dir = 'input/' 58 master_file = 'input/items.csv' 59 pattern_s = 'sales_raw_' 60 pattern_e = '.csv' 61 pattern_year = "201611" 62 63 items = master_to_itemdict(master_file) 64 make_sales_files(data_dir, pattern_s, pattern_e, pattern_year) 65 read_sales_files(sales_files, items) 66 write_total_sales(total_sales, 'output/sales.csv')

投稿2021/05/13 04:55

ppaul

総合スコア24670

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

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

退会済みユーザー

退会済みユーザー

2021/05/13 05:07

ご回答頂き、ありがとうございます。 また、私のためにプログラムをご準備いただき誠にありがとうございます。。! > プログラミングの勉強ということであれば、まず全体構造を見直しましょう。 かしこまりました。アドバイスありがとうございます。 この少しの間で、バグを残しつつここまで手を加えることが出来るのですね。。! 頂いたプログラムを解読して、修正してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問