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

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

詳細はこちら
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Python 3.x

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

Q&A

解決済

4回答

1047閲覧

データの持ち方を変更したい

kumer1

総合スコア26

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Python 3.x

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

0グッド

0クリップ

投稿2019/11/02 15:46

前提・実現したいこと

スプレッドシートまたはCSVにて下記図Aのように1行で格納している複数の列データを、スプレッドシートまたはCSVにて図Bのように複数行に分解して出力したいです。会社によって単価・数量が変化します。1しかない場合もあるし、3まである場合もあり、会社によりまちまちです。

使用する言語はPythonまたはGASにて行いたいです。

◾️図A
|会社名|単価1|数量1|単価2|数量2|単価3|数量3|
|:--|:--:|--:|
|株式会社A|380|50|3000|2|5000|10|
|株式会社B|50|100|8000|1|||

◾️図B

会社名単価数量
株式会社A38050
株式会社A30002
株式会社A500010
株式会社B50100
株式会社B80001

どのように記述していいかアイデアが出てこないのでご教授宜しくお願い致します。

補足情報(FW/ツールのバージョンなど)

mac OS High Sierra, Python3

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

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

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

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

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

guest

回答4

0

javascript

1function q220924() { 2 const csvId = '****'; 3 const dat = Utilities.parseCsv(DriveApp.getFileById(csvId).getBlob().getDataAsString(), ',').slice(1).reduce(function (a, c) { 4 return a.concat(c); 5 }, []); 6 SpreadsheetApp.getActive().insertSheet().getRange(1, 1, dat.length + 1, 3).setValues([["会社", "単価", "数量"]].concat(dat)); 7} 8 9function chunk(row) { 10 const company = row[0]; 11 return row.slice(1).filter(function (e) { 12 return e !== ""; 13 }).reduce(function (a, _, i, array) { 14 if (!(i % 2)) { 15 a.push([company, array[i], array[i + 1]]); 16 ; 17 } 18 return a; 19 }, []) 20}

投稿2019/11/05 15:40

papinianus

総合スコア12705

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

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

0

Pythonで実施する場合はこんな感じできると思います。

Python

1import pandas as pd 2 3# NaNが混在している列が浮動小数点になるのを回避するため「dtype=str」をつけて文字列として扱う 4df = pd.read_csv('input.csv', dtype=str) 5 6print(df) 7""" 8 会社名 単価1 数量1 単価2 数量2 単価3 数量3 90 株式会社A 380 50 3000 2 5000 10 101 株式会社B 50 100 8000 1 NaN NaN 11""" 12 13columns = [ ['単価1', '数量1'], ['単価2', '数量2'], ['単価3', '数量3'] ] 14 15# 列名を変えながら結合 16df = pd.concat([ df.loc[:,['会社名', x[0], x[1]]].rename(columns={ x[0] : '単価', x[1]: '数量'}) for x in columns ]) 17 18# NaNがある行をdrop&ソート&index振り直し 19df = df.dropna(how='all',subset=['単価', '数量']).sort_values(by=['会社名']).reset_index(drop=True) 20 21print(df) 22""" 23 会社名 単価 数量 240 株式会社A 380 50 251 株式会社A 3000 2 262 株式会社A 5000 10 273 株式会社B 50 100 284 株式会社B 8000 1 29""" 30 31df.to_csv('output.csv', index=False)

投稿2019/11/02 23:26

nomuken

総合スコア1627

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

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

kumer1

2019/11/03 13:57

ありがとうございました。 実現できました。
guest

0

はいでは、プログラムの基本的なことを教わってなく、完全独学で勉強してる私がとりあえず先に回答しておきます。

GAS

1function myFunction() { 2 3 var sh = "シート化します" 4 var arr = sh.getRange("タイトル除いた最初~最後まで").getValues() 5 var arr2 = [] 6 var record = [] 7 var kaisya = [] 8 9 10 for (var a = 0; a < arr.length;a++) 11 { 12 kaisya = arr[a][0]//会社名だけ別においとく。2行目になったら二行目の会社名をとる 13 for (var b = 0; b < arr[a].length; b++) 14 { 15 16 var num = arr[a][b*2+1]//単価情報 17 var num2 = arr[a][b*2+2]//数量情報 18 if(num == undefined || num == ""){break;} 19 record.push(kaisya,num,num2)//図Bのようにrecord = [会社名,単価,数量]にする 20 arr2.push(record)//そのレコードをプッシュする 21 record = []//レコードをまっさらにする。 22 } 23 24 } 25 26 sh.getRange("開始Row","開始Col",arr2.length,arr2[0].lenth).setValues(arr2) 27 28} 29

実際にシート化したりレンジ充てたりしてないのでちゃんと動くかは不明ですので発想だけを伝えますと、

forの中にfor文をいれて、
1つめのfor文には会社名をコピーして、2つめのfor文で2つづつ取っていって、それをレコード化しています。

ごり押しな考え方なので、単価、数量以外に何かはいったりしたら正しい結果になりません。

もう少し待てばもっと素晴らしい回答が頂けると思うので、とりあえず先にこの発想で組んでみて下さい。

投稿2019/11/02 16:12

編集2019/11/03 03:00
takaD

総合スコア315

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

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

kumer1

2019/11/03 13:57

ありがとうございました。実現できました。
guest

0

ベストアンサー

c.py

python3

1import csv 2import pprint 3 4with open('data.csv') as f: 5 reader = csv.DictReader(f) 6 rows = [row for row in reader] 7 8# pprint.pprint(rows) 9rows2 = [] 10for row in rows: 11 camp = row["会社名"] 12 for key in row.keys(): 13 if key.startswith("単価"): 14 key_num = key.replace("単価", "数量", 1) 15 if row[key] and row[key_num]: 16 rows2.append({"会社名": camp, "単価": row[key], "数量": row[key_num]}) 17 18# pprint.pprint(rows2) 19 20with open('data2.csv', 'w') as f: 21 writer = csv.DictWriter(f, ["会社名", "単価", "数量"]) 22 writer.writeheader() 23 for row in rows2: 24 writer.writerow(row)

実行例:
イメージ説明

参考情報

  • PythonでCSVファイルを読み込み・書き込み(入力・出力)

https://note.nkmk.me/python-csv-reader-writer/

投稿2019/11/03 01:46

katoy

総合スコア22324

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

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

kumer1

2019/11/03 13:58

ありがとうございました。応用できやすかったのでベストアンサーにさせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問