前提・実現したいこと
現在以下のように入力されているcsv(元はExcel)があります。
大分類 | 品目 |
---|---|
野菜 | ニンジン |
野菜 | にがうり |
野菜 | ピーマン |
果物 | りんご |
果物 | みかん |
花 | チューリップ |
花 | 桜 |
これを、下のようなデータに書き換えたいと思っています。
大分類 | 品目 |
---|---|
野菜 | ニンジン,にがうり,ピーマン |
果物 | りんご,みかん |
花 | チューリップ,桜 |
csvの編集といえばVBAかPythonなのかなと思い
せっかくだからとPythonの文法を調べている段階です。
発生している問題・エラーメッセージ
以下のようなフローを考えました。(用語の不正確さはご容赦ください)
- 元となる配列(今回はcsv)を準備する
- 元となる配列をforで回す
- 何らかの変数を準備して、初出の大分類をキーにした空配列を作る
- 既出の大分類が出現したら品目の要素を↑の配列に入れてから削除する
- もう一度forを回して、↑の情報を上書きしていく
もっとすっきり書けないものかと思うのですが、どうにも良い方法が思いつきません。
今回の場合、どのような考え方で処理を行っていくのが正解でしょうか。
該当のソースコード
考え方の時点で?となったので、コードはcsvをprintするところで止まっています。
python
1import pandas as pd 2 3df = pd.read_csv('test.csv').values.tolist() 4 5for key,value in enumerate(df): 6 print("{0} = {1[0]}".format(key,value))
補足情報(FW/ツールのバージョンなど)
Python:3.6
追記
ひとまず書けるところまで書いてみました。(当初の考え方とは変わってしまいましたが…)
思っているような結果が出ることは確認済みです。
メソッドの書き方がこれで本当に正しいのかは自信がありません。
python
1class Sample: 2 3 def __init__(self, readCsvFile, writeCsvFile): 4 self.readCsvFile = readCsvFile 5 self.writeCsvFile = writeCsvFile 6 7 def read(self): 8 import pandas as pd 9 return pd.read_csv(self.readCsvFile).values.tolist() 10 11 def edit(self, df): 12 from itertools import groupby 13 14 # 大分類初出リスト 15 firstAppearanceList = [] 16 # 項目リスト 17 itemsList = [] 18 19 for key, group in groupby(df, key=lambda x: x[0]): 20 # 大分類をまたいだ項目の重複は可とする(野菜のスイカと果物のスイカは別扱い) 21 seen = [] 22 firstAppearanceList.append(key) 23 itemsList.append(','.join([x[1] for x in list(group) if x[1] not in seen and not seen.append(x[1])])) 24 25 return list(zip(firstAppearanceList, itemsList)) 26 27 def write(self, list): 28 import csv 29 f = open(self.writeCsvFile, 'w') 30 writer = csv.writer(f, lineterminator='\n') 31 writer.writerows([x for x in list]) 32 33def done(readCsvFile, writeCsvFile): 34 sample = Sample(readCsvFile, writeCsvFile) 35 df = sample.read() 36 list = sample.edit(df) 37 sample.write(list) 38 39print('インポート(加工)したいcsvのファイル名を入力してください。') 40readCsvFile = input('>> ') or 'test.csv' 41print('エクスポートする際のcsvのファイル名を入力してください。') 42writeCsvFile = input('>> ') or 'tmp.csv' 43done(readCsvFile, writeCsvFile)