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

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

詳細はこちら
CSV

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

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

207閲覧

python pandas csvデータの抽出について

退会済みユーザー

退会済みユーザー

総合スコア0

CSV

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

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2019/11/11 04:22

pythonのpandasを使用し、元のdata.csvデータから値を抽出しlist.csvに出力したいと考えております。

data.csv[id,id2,cost]:[1,10,5][2,10,3][3,10,1][1,13,10][2,13,5][3,13,4]......

list.csv[id2,min]:[10, ][13, ]...

といった内容になっております。

data.csvのid2の値に対してcostが一つであれば、list.csvのminに入る値は一つに決まるのですが、data.csvのid2の値に対してcostが複数ある場合(今回は3つ)に、最小となるcostをlist.csvに出力するにはどのようにしたらよいでしょうか。

list.csvにおいてid2が10の時には1を、13の時には4を出力したいです。

なお、data.csvにおいてid2が1つである場合には、list.csvのminは1つに決まると思いますが、その時のスクリプトは以下になります。

python

1import pandas as pd 2 3df = pd.read_csv("data.csv") 4df1 = pd.read_csv("list.csv") 5new_file = "data_min.csv" 6results = df.merge(df1,on="id2") 7results.to_csv(new_file,index=False)

上記について教えていただけたらと思います。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

これで良いのではないでしょうか?

Python

1df1['min'] = df1['id2'].map(df.groupby('id2')['cost'].min())

少し説明を加えると

  1. df.groupby('id2')['cost'].min() にて df(data.csv)のデータフレームを id2の値ごとにcost列が最小の値を導く
  2. df1['id2'].map(...) にて上記の結果を df1(list.csv)のid2列の値で引き当てる
  3. 結果をdf1のmin列に格納する

を行っております。


動作サンプルコード

Python

1import pandas as pd 2import io 3 4data_csv = """ 5id,id2,cost 61,10,5 72,10,3 83,10,1 91,13,10 102,13,5 113,13,4 12""" 13 14df = pd.read_csv(io.StringIO(data_csv)) 15print(df) 16# id id2 cost 17#0 1 10 5 18#1 2 10 3 19#2 3 10 1 20#3 1 13 10 21#4 2 13 5 22#5 3 13 4 23 24conv = df.groupby('id2')['cost'].min() 25print(conv) 26#id2 27#10 1 28#13 4 29 30list_csv = """ 31id2,min 3210, 3313, 34""" 35df1 = pd.read_csv(io.StringIO(list_csv)) 36print(df1) 37# id2 min 38#0 10 NaN 39#1 13 NaN 40 41ret = df1['id2'].map(conv) 42print(ret) 43#0 1 44#1 4 45#Name: id2, dtype: int64 46 47df1['min'] = ret 48print(df1) 49# id2 min 50#0 10 1 51#1 13 4

投稿2019/11/11 05:17

編集2019/11/11 10:45
magichan

総合スコア15898

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

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

退会済みユーザー

退会済みユーザー

2019/11/11 06:24

magichanさん> ありがとうございます。 ご教授いただいた内容から自分で作成したスクリプトの下3行は削除してよいと判断し、 次のようにスクリプトを変更したのですが、結果がdf1のminに格納されませんでした。(エラーメッセージはありませんでした) どういった原因が考えられますでしょうか。 お手数をおかけいたしますが、どうぞよろしくお願いいたします。 import pandas as pd df = pd.read_csv("data.csv") df1 = pd.read_csv("list.csv") df1["min"] = df1["id2"].map(df.groupby("id2")["cost"].min())
magichan

2019/11/11 07:46

ん、なんでだろ? とりあえず print(df.groupby("id2")["cost"].min()) や print(df1["id2"].map(df.groupby("id2")["cost"].min())) とすると、何が表示されますか?
退会済みユーザー

退会済みユーザー

2019/11/11 08:16

0 1 1 4 Name: id2, dtype: int64 プログラム 'python.exe' はコード 0 (0x0) で終了しました。 エラーメッセージはないのですが、list.csvのmin列に出力されないといった状況です。
magichan

2019/11/11 10:47

とりあえず、実際のデータにて動作するサンプルコードを追記しました。 このまま実行すると動作すると思いますので、ご自身のデータとどのように違うのかを確認してみてください。
退会済みユーザー

退会済みユーザー

2019/11/12 04:24

ご教授いただいた内容で動作いたしました。 ありがとうございました。 もう一点ご質問よろしいでしょうか。 基本は上記同様にdata.csvのid2に着目してcostが最小の値をlist.csvのminに出力するのですが、今回新たにid2がminを取る時のdata.csvのid(1,2,3)にも着目したいと考えております。 具体的には、同じ番号のidの最小値を取れる回数に制限を設け(id:1⇒2回、id2⇒2回、id3⇒1回まで)最小値を取るidが制限に達した場合、そのidはminを取る場合であっても、制限に達していないidのうちから最小値を選択するようにするにはどのように変更したらよいでしょうか。 data.csv[id,id2,cost]:[1,10,5][2,10,3][3,10,1][1,13,10][2,13,5][3,13,4][1,18,1][2,18,5][3,18,10][1,20,10][2,20,5][3,20,4][1,25,10][2,25,1][3,25,5]...... list.csv[id2,min]:[10, 1][13, 5][18,1][20,5][25,10]...... のように出力したいです。 id2が10の時は最小値が1なのでlist.csvのminには1が出力されます。 (この時のidは3⇒制限回数1回に達したので最小値であってもidが3のものは以降使用できない) id2が13の時の最小値は4ですが、id3のものは使用できない為、2番目に小さい5をlist.csvのminに出力します。(この時のidは2) (最後の方になると、使用できるidの制限でmaxがlist.csvのminに出力されることもあり得ます。。。) このようにlist.csvの上から5列目までこの動作を繰り返すにはどのように変更したらよろしいでしょうか。 なお、list.csvの6列目以降のminに関しては出力しなくて結構です。(id:1,2,3の制限の合計が5である為、6行目以降は全てのidが制限に達する為です。) お忙しいところ申し訳ございません。 ご教授いただけましたら幸いです。 よろしくお願いいたします。
magichan

2019/11/12 07:39

ざっと上記仕様を見ました。 簡単に実現できるのであれば回答しようかと思っておりましたが、残念ながら現状のコードを少し改変すると解決できるようなものではなく、全く違うアプローチを考える必要がありそのです。 ですので大変申し訳有りませんが、これは別の質問として立てていただいた方がよいかと思います
退会済みユーザー

退会済みユーザー

2019/11/12 07:44

全く違うアプローチが必要とのこと、承知いたしました。 ご丁寧にご回答いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問