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

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

新規登録して質問してみよう
ただいま回答率
85.35%
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

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

pandas

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

Q&A

解決済

4回答

1194閲覧

python: データの条件抽出における非効率さを直したい (動的変数定義しか道はないのだろうか...?)

f001

総合スコア11

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

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

pandas

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

1グッド

2クリップ

投稿2021/01/17 03:57

#最終目的:カテゴリーごとにデータを分け、それぞれのデータに対して分析を行いたい

最終目的のため、データをカテゴリーごとに分けたいと思っていますが、今回の問題はそこにあります。


以下を変数名 df に格納。
![イメージ説明]

上記データについて、カテゴリーごとにその行のデータを抽出する場合、(今回はカテゴリーaのデータを抽出)

python

1df_a = df[df['カテゴリー'] == "a"] 2 3#もしくは 4df_a = df.query('カテゴリー == "a"')

というコードで、以下のカテゴリーaのデータが抽出できます。(df_aを表示)

イメージ説明

ここまではいいのですが、如何せんこの後が問題で、
もしカテゴリーの種類が多い場合には、(a,b,c,d,...,zまでとか)

python

1df_a = df[df['カテゴリー'] == "a"] 2df_b = df[df['カテゴリー'] == "b"] 3df_c = df[df['カテゴリー'] == "c"] 4df_d = df[df['カテゴリー'] == "d"] 5... 6df_z = df[df['カテゴリー'] == "z"]

というように今まで書いてきており...凄まじいほどに可読性が悪く、非効率です。

自分しか読まないかつ動かさないコードのため、このような形でいいかと思い進めてきたのですが、いい加減直したいと思い、こちらに投稿をしています。

これに対して、動的変数定義と呼ばれる概念(?)があるということは突き止め、そちらで書いてみたはいいのですが (forで exec とかを使う)、如何せん処理が遅いということと、他の方の個人blogや質問を見るに、あまり褒められた方法ではないという気がしています。

"目的"にあるように、以降 df_a のような変数に格納したカテゴリーごとのデータに対し、分析を行いたい次第となってはいますが(時系列解析とか)、上記カテゴリーごとのデータ抽出の方法において、何か別の書き方などはありますでしょうか。
もしくは、そもそもこのような形で変数ごとにデータを格納したいと考えることが間違いだという場合には、そちらに関しても何か改善案等ございましたら、頂けますと幸いです。

※Google Colaboratory

A_kirisaki👍を押しています

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

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

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

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

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

guest

回答4

0

groupby() を使いましょう!
例えば

Python

1>>> df = pd.DataFrame([{'category':random.choice(['a','b','c']),'price':random.choice([1000,2000,3000,4000,5000]),'amount':random.choice(list(range(5)))} for _ in range(20)]) 2>>> df 3 category price amount 40 b 3000 1 51 c 4000 4 62 c 3000 2 73 a 1000 2 84 c 5000 3 95 b 1000 3 106 c 5000 4 117 c 1000 0 128 c 2000 3 139 b 4000 0 1410 c 4000 1 1511 c 5000 4 1612 a 5000 4 1713 c 1000 1 1814 c 4000 0 1915 b 1000 4 2016 a 5000 2 2117 b 5000 2 2218 c 1000 2 2319 b 4000 2

こんなデータがあったとして、gropuby() をすると

Python

1>>> ([print(x) for x in df.groupby('category').category]) 2('a', 3 a 312 a 416 a 5Name: category, dtype: object) 6('b', 0 b 75 b 89 b 915 b 1017 b 1119 b 12Name: category, dtype: object) 13('c', 1 c 142 c 154 c 166 c 177 c 188 c 1910 c 2011 c 2113 c 2214 c 2318 c 24Name: category, dtype: object) 25[None, None, None]

というデータが得られます。カテゴリーごとに合計を得たければ

Python

1>>> df.groupby('category').sum() 2 price amount 3category 4a 11000 8 5b 18000 12 6c 35000 24

で一発ででますし、カテゴリーにアクセスしたければ

Python

1>>> df.groupby('category').get_group('a') 2 category price amount 33 a 1000 2 412 a 5000 4 516 a 5000 2

で出来ます。いかがでしょう?

投稿2021/01/17 04:30

A_kirisaki

総合スコア2853

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

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

0

ベストアンサー

例えば以下のように書き方はどうでしょう。

Python

1df_dict = dict() # カテゴリごとのデータフレームを格納する辞書 2 3for category in df["カテゴリー"].unique(): # dfの"カテゴリー"の種類別に 4 df_dict[category] = df(df["カテゴリー"] == category)

例えば、df_dict['a']にはカテゴリー'a'のデータが格納されます。

投稿2021/01/17 04:19

Amakaze

総合スコア313

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

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

0

カテゴリーと取引日付でソートしてから、カテゴリーをインデックスにしてしまえばいいのでは。

Python

1import pandas as pd 2import io 3 4txt = """ 5取引日付,カテゴリー,金額,数量 62017/2/16,a,1000,2 72017/5/14,a,1500,1 82017/5/22,b,3000,1 92017/6/15,b,4000,1 102017/8/27,c,500,4 112017/7/8,b,3000,1 122017/3/16,a,2000,2 132017/4/25,a,2000,1 142017/8/26,c,500,3 152017/7/12,b,3000,1 16""" 17 18df = pd.read_csv(io.StringIO(txt), parse_dates=['取引日付']) 19df = df.sort_values(['カテゴリー', '取引日付']) 20df.set_index(['カテゴリー'], inplace=True) 21print(df) 22 23category = list(dict.fromkeys(df.index)) # 一意なカテゴリーのリスト 24for cat in category: 25 print(df[cat:cat]) 26 print("-" * 32)

results

1 取引日付 金額 数量 2カテゴリー 3a 2017-02-16 1000 2 4a 2017-03-16 2000 2 5a 2017-04-25 2000 1 6a 2017-05-14 1500 1 7b 2017-05-22 3000 1 8b 2017-06-15 4000 1 9b 2017-07-08 3000 1 10b 2017-07-12 3000 1 11c 2017-08-26 500 3 12c 2017-08-27 500 4 13 取引日付 金額 数量 14カテゴリー 15a 2017-02-16 1000 2 16a 2017-03-16 2000 2 17a 2017-04-25 2000 1 18a 2017-05-14 1500 1 19-------------------------------- 20 取引日付 金額 数量 21カテゴリー 22b 2017-05-22 3000 1 23b 2017-06-15 4000 1 24b 2017-07-08 3000 1 25b 2017-07-12 3000 1 26-------------------------------- 27 取引日付 金額 数量 28カテゴリー 29c 2017-08-26 500 3 30c 2017-08-27 500 4 31--------------------------------

投稿2021/01/17 04:35

Daregada

総合スコア11990

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

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

0

evalを使うのはお勧めしませんが、globals()を使う方は安全で性能も良いと思います。

python

1>>> for i in ['a', 'b', 'c']: 2... globals()['df_'+i] = 'sample_' + i 3... 4>>> print(df_a) 5sample_a 6>>> print(df_b) 7sample_b 8>>> print(df_b) 9sample_b 10>>> print(df_c) 11sample_c

のような使い方です。

もっとも、普通にリストに入れた方が、後も楽です。

投稿2021/01/17 04:15

ppaul

総合スコア24670

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問