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

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

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

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

Q&A

解決済

4回答

2352閲覧

毎日データがばらばらのPOSデータをcsvファイルにうまくまとめたい

hermitcrab56

総合スコア1

Python

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

0グッド

0クリップ

投稿2020/08/07 03:20

こんにちは。
私は飲食店で働いていて、お店のPOSデータがスクレイピングできるようになったので
その日のフードやドリンクの出数などを毎日csvファイルにまとめて後日分析できるようにしたいのですが、
POSデータがその日に売れた商品のみ記録、表にしているため毎日データがばらばらです。

具体的には、
7月11日
バーガーA:10個
バーガーB:12個
ドリンクA:8個

7月12日
バーガーA:9個
バーガーC:3個
ドリンクB:7個
デザートA:1個

といった形です。
その日のデータだけなら、各商品名をヘッダーにして数量をcsvファイルに出力することができるのですが、
後日ヘッダーにない商品が出てきた際にcsvファイルを作り直すもしくは追記する方法としてよい方法が思いつきません。
例えば、
||バーガーA|バーガーB|ドリンクA|
|:--:|:--:|:--:|:--:|
|7月11日|10個|12個|8個|

としていたものを

バーガーAバーガーBバーガーCドリンクAドリンクBデザートA
7月11日10個12個0個8個0個0個
7月12日9個0個3個0個7個1個

というように拡張してcsvファイルに保存したいです。
理由はこのような形のほうがpandasなどで分析する際にやりやすいと考えているからです。
現状、csvファイルを作る際には、seleniumのwebdriverでスクレイピングしたデータをBeautifulSoupでパースして、テキストデータを辞書型として変数に格納して、ライブラリcsvのDictWriteで書き込んでいます。
既存のライブラリ、サードパーティーのライブラリ含めてよい方法があればご教授願います。

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

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

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

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

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

hentaiman

2020/08/07 05:03

一般的な飲食店ではメニューが可変なので、質問者の希望するデータの持ち方だと無限にヘッダーが増え続ける事になりますが問題無いですか?
guest

回答4

0

ベストアンサー

pandasのmerge関数を使えば同じカラム名でマージをしてくれます。

python

1import pandas as pd 2from io import StringIO 3 4s1 = '''日付,バーガーA,バーガーB,ドリンクA 52020/07/11,10個,12個,8個''' 6df1 = pd.read_csv(StringIO(s1)) 7 8s2 = '''日付,バーガーA,バーガーC,ドリンクB,デザートA 92020/07/12,9個,3個,7個,1個''' 10df2 = pd.read_csv(StringIO(s2)) 11 12dfm = pd.merge(df1, df2, how='outer').fillna('0個') 13print(dfm) 14 15''' 16 日付 バーガーA バーガーB ドリンクA バーガーC ドリンクB デザートA 170 2020/07/11 10個 12個 8個 0個 0個 0個 181 2020/07/12 9個 0個 0個 3個 7個 1個 19'''

投稿2020/08/07 05:04

yureighost

総合スコア2183

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

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

hermitcrab56

2020/08/07 06:54

マージとは!?StringIO!?という状態でしたが、調べてみて現状自分が最も理想としている入力→出力の形に近いと感じました。 StringIOも便利で、テストの段階においてすごく役に立ちそうです。 回答ありがとうございました。
guest

0

理由はこのような形のほうがpandasなどで分析する際にやりやすいと考えているからです。

商品の種類が増える可能性があるのであればデータは「縦持ち」のほうがよいです。
横持にしたければpivot_tableを使えばよいです。

追記

たとえば「商品」ではなく「ハンバーガー」「ジュース」などの大まかな商品グループ毎に集計したくなった場合、横持だと大変です。
縦持ちなら、集計対象でグルーピングしてpivot_tableするだけですみます。

Python

1import pandas as pd 2import numpy as np 3 4# テストデータ。日々追記される 5from io import StringIO 6s = """日付,商品,個数 72020/07/11,バーガーA,10 82020/07/11,バーガーB,12 92020/07/11,ドリンクA,8 102020/07/12,バーガーA,9 112020/07/12,バーガーC,3 122020/07/12,ドリンクB,7 132020/07/12,デザートA,1""" 14df = pd.read_csv(StringIO(s)) 15 16# 個数を集計して、ついでに合計行と列も出す(margins=True) 17df2 = pd.pivot_table(df, index='日付', columns='商品', values='個数', margins=True, aggfunc=np.sum) 18df2 = df2.fillna(0) 19print(df2) 20#商品 デザートA ドリンクA ドリンクB バーガーA バーガーB バーガーC All 21#日付 22#2020/07/11 0.0 8.0 0.0 10.0 12.0 0.0 30 23#2020/07/12 1.0 0.0 7.0 9.0 0.0 3.0 20 24#All 1.0 8.0 7.0 19.0 12.0 3.0 50 25 26 27# 商品グループ毎に同様の集計を行う 28 29df['商品グループ'] = df['商品'].str.replace('[A-Z]','') 30 31df2 = pd.pivot_table(df, index='日付', columns='商品グループ', values='個数', margins=True, aggfunc=np.sum) 32df2 = df2.fillna(0) 33print(df2) 34#商品グループ デザート ドリンク バーガー All 35#日付 36#2020/07/11 0.0 8.0 22.0 30 37#2020/07/12 1.0 7.0 12.0 20 38#All 1.0 15.0 34.0 50

投稿2020/08/07 04:34

編集2020/08/07 08:02
can110

総合スコア38339

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

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

hermitcrab56

2020/08/07 07:32 編集

エッ!どうして縦なの!? なんとなくだけどFinancialTimes読んでそうだね! なんとなくだけど。 回答ありがとう!
can110

2020/08/07 08:03

例を追記しました。 横持だったら大変じゃないですか?
guest

0

CSVファイルを保存する際の一案です。

CSVファイルの保存の際、1行目を必ずヘッダーにしておきます。1カラム目は日付、その後のカラムはN個の品種です。
※見易くするために行末に$を挿入します。これは特に必須ではありませんが、データ内容とプログラムによっては整合性をとる際に有用となることがあります。
(※CSV(カンマ区切り)では不要な配慮だったので取り消します。TSV(タブ区切り)のデータで末尾の方で連続の空文字があったときに不具合が出たときの話でしたので、この点は忘れてください)

ある日のCSVファイル

CSV

1"日付","バーガーA","バーガーB","ドリンクA" 27月11日,10,12,8

品種名をヘッダー部に保存しておけば、対応するカラム位置がそれと分かります。日ごとに過不足があってもマージするときに判断できるはずです。key=valueの辞書形式としても扱い易いでしょう。

複数日分をマージ後のCSVファイル

CSV

1"日付","バーガーA","バーガーB","バーガーC","ドリンクA","ドリンクB","デザートA" 27月11日,10,12,0,8,0,0 37月12日,9,0,3,0,7,1

投稿2020/08/07 03:46

編集2020/08/07 03:59
dodox86

総合スコア9254

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

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

hermitcrab56

2020/08/07 07:35

入力→ファンクション→出力 とあって、 ご提案いただいた方法は理想的な出力の一つです! 悩んでいるのはバラバラの入力に対するファンクションの部分! 回答ありがとう!
dodox86

2020/08/07 07:42

コメントありがとうございます。ご質問の文中で既にpandas, DictWriterなどの単語が書かれ、機能の実装部分にお悩みということが示唆されていたので、私自身も読みが浅かったようです。他回答者様の内容も含め、私も勉強になりました。
hermitcrab56

2020/08/07 13:03

見ず知らずのド素人の質問に真摯に対応していただいて感謝しています。 またなにかあったら力になって欲しいです! アイコンの鳥もかわいいね!クエッ!
guest

0

品種ごとに変数を用意しといて、一日ごとにカウントしていくようなコードを組んでいけばいいです

投稿2020/08/07 03:23

y_waiwai

総合スコア88024

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問