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

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

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

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

pandas

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

Q&A

解決済

2回答

1945閲覧

pandasにおける、項目ごとに異なる条件を適用した集計方法(groupby,sum,agg,apply,ユーザ定義関数)

papasim824

総合スコア1

Python

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

pandas

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

0グッド

0クリップ

投稿2021/08/17 01:45

編集2021/08/17 01:47

やりたい事

df-Aをdf-Bのように集計したい。

  • df-A(契約ごとの明細データ)
日本語名項目名データ型項目値
申込番号mno数値-
支社sya数値-
営業所kan数値-
金額kinngaku数値契約した金額を保持
契約者性ksex数値0:男性 1:女性
契約経路keiro数値0:新規 1:見直し
  • df-B(支社、営業所ごとに各種項目を集計)
日本語名項目名データ型項目の組成
支社sya数値=支社
営業所kan数値=営業所
金額kinngaku数値金額を集計する。
金額_男性kinngaku_man数値契約者性=0のレコードの金額を集計する。
金額_女性kinngaku_woman数値契約者性=1のレコードの金額を集計する。
金額_男性_新規kinngaku_man_sin数値契約者性=0,契約経路=0のレコードの金額を集計する。
金額_男性_見直しkinngaku_man_mina数値契約者性=0,契約経路=1のレコードの金額を集計する。
金額_女性_新規kinngaku_woman_sin数値契約者性=1,契約経路=0のレコードの金額を集計する。
金額_女性_見直しkinngaku_woman_mina数値契約者性=1,契約経路=1のレコードの金額を集計する。

知りたい事

  • aggを利用した際、引数に複数列を渡す方法

→集計列以外の列を条件に利用する方法が分からず。
複数項目を異なる条件で集計できるが、ユーザー定義関数を用いても引数は1列しか渡せない?
(「金額_男性」「金額_女性」といった集計は不可?)

  • applyを利用した際に、複数項目を異なる条件で同時に集計する方法

→データフレームを引数として渡せるので、集計列と条件列を分けることができるが、複数項目を異なる条件で同時に集計できない
(「金額_男性」「金額_女性」を同時に集計することは不可?)

  • あるいはもっと効率的にやりたいことを実現できる方法

試したこと

  • agg

→ 検索等行ったものの情報が見つからず、異なる引数の渡し方が分からず。。

  • apply

→同一のデータフレームに対して、groupbyと同時に複数回applyを掛ける。⇒エラー
``` python
def udf_kingaku_man(df):
return df.query('ksex==1')['kingaku'].sum()

def udf_kingaku_woman(df): return df.query('ksex==2')['kingaku'].sum() df_group = df.groupby(['sya','kan']).apply(udf_kingaku_man).apply(udf_kingaku_woman).reset_index()
* 集計したい項目ごとに、同一のデータフレームにgroupby+applyを掛け、異なるデータフレームを作成したのち、必要列のみコンカチ。⇒実現できるが冗長? ``` python df_group1 = df.groupby(['sya','kan']).apply(udf_kingaku_man).reset_index() df_group2 = df.groupby(['sya','kan']).apply(udf_kingaku_woman).reset_index() # 列除外は省略 df_group = pd.concat([df_group1, df_group2], axis=1)

※初心者マークを付加

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

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

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

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

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

guest

回答2

0

ベストアンサー

applyする関数で、Seriesを返すようにすればいいです。
(作りたいDataFrameのcolumnが、返すSeriesのindexになります)

python

1def func(df): 2 m0 = df.loc[(df['ksex'] == 0) & (df['keiro'] == 0), 'kinngaku'].sum() 3 m1 = df.loc[(df['ksex'] == 0) & (df['keiro'] == 1), 'kinngaku'].sum() 4 w0 = df.loc[(df['ksex'] == 1) & (df['keiro'] == 0), 'kinngaku'].sum() 5 w1 = df.loc[(df['ksex'] == 1) & (df['keiro'] == 1), 'kinngaku'].sum() 6 7 return pd.Series({ 8 'kinngaku': m0 + m1 + w0 + w1, 9 'kinngaku_man': m0 + m1, 10 'kinngaku_woman': w0 + w1, 11 'kinngaku_man_sin': m0, 12 'kinngaku_man_mina': m1, 13 'kinngaku_woman_sin': w0, 14 'kinngaku_woman_mina': w1, 15 }) 16 17df_group = df.groupby(['sya','kan']).apply(func).reset_index()

下記のようにpandas.pivot_tableを使ってやる方が速いんじゃないかという気がします。
(実データで試さないとわからないです)

python

1df2 = pd.pivot_table(df, 'kinngaku', 2 index=['sya', 'kan'], columns=['ksex', 'keiro'], 3 aggfunc='sum', fill_value=0) 4df2.columns = df2.columns.map({ 5 (0, 0): 'kinngaku_man_sin', 6 (0, 1): 'kinngaku_man_mina', 7 (1, 0): 'kinngaku_woman_sin', 8 (1, 1): 'kinngaku_woman_mina', 9}) 10df2['kinngaku_man'] = df2['kinngaku_man_sin'] + df2['kinngaku_man_mina'] 11df2['kinngaku_woman'] = df2['kinngaku_woman_sin'] + df2['kinngaku_woman_mina'] 12df2['kinngaku'] = df2['kinngaku_man'] + df2['kinngaku_woman']

大きくグループ化して、applyの中で分割計算する処理をいれるか、
小さくグループ化して、結果を足し合わせるかの違いです。

投稿2021/08/17 07:00

編集2021/08/17 08:11
bsdfan

総合スコア4794

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

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

papasim824

2021/08/17 12:18

記述例までご丁寧にありがとうございます。 手元の環境に組み込んだところ、希望する結果を得ることが出来ました!
guest

0

note.nkmk.me pandas を一通り読みましょう。

それで分からないようであれば、お金を払って誰かに作ってもらうことを検討した方が良いでしょう。

投稿2021/08/17 01:59

ppaul

総合スコア24670

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

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

papasim824

2021/08/17 12:18

参考サイトを教えていただきありがとうございます! 基礎から勉強いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問