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

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

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

Pythonistaは、iOS上でPythonプログラミングができる開発アプリです。さらに、Pythonの関数・変数などを自動で補完する便利なコードエディタや、PythonスクリプトをiOS上で多様な形で機能させる各種機能も内包しています。

pandas

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

Q&A

解決済

2回答

433閲覧

データフレーム内の数値を、if文で複数分岐してセルの合計値を出したい

karakarakarappo

総合スコア28

Pythonista

Pythonistaは、iOS上でPythonプログラミングができる開発アプリです。さらに、Pythonの関数・変数などを自動で補完する便利なコードエディタや、PythonスクリプトをiOS上で多様な形で機能させる各種機能も内包しています。

pandas

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

0グッド

0クリップ

投稿2022/09/26 14:39

実現したいこと

データフレーム内の条件で指定した2つのセルの合計値を出す、又は対象のセルに値がある場合はその値をセルに代入する
ということを実現したいです。

具体的には、以下表を参照してください。
表①から表②のように、「計算結果」を、データフレーム内で計算をしたいです。

【表①】

ABC
9/1011
9/200
9/300
9/4100
9/500
9/610
9/7125

⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓

【表②】

ABC計算結果
9/101111
9/20011
9/30011
9/410021
9/50021
9/61022
9/712525

エクセルの計算式で書くとすると、
「=if(C3<>0,C3,計算結果2+B3)」
という感じになると思います。

なぜこれを実現しないといけないのか

現在売上高を集計し、Matplotlibで描画をすることを想定した、
以下の条件のあるデータフレームを作成しているためです。

date当日分売上仮売上高合計確定売上高合計暫定売上高合計(集計部分)
2022/7/100100100
2022/7/21002000300
2022/7/3200300600600
2022/7/42005000800
2022/7/505000800
2022/7/640090001200
2022/7/7100100010001000

列「当日分売上」というのは、各担当から申告があった数値を毎日反映し、
列「仮売上高合計」はその当日売上をcumsumで集計しています。
確定売上高合計は、ランダムな日にちで、確定した売上高合計の情報が入手でき、
それまでの集計を無視して、「確定売上高合計」と「暫定売上高合計(集計部分)」に正しい数値が入ります。

試したこと

確定売上高合計の1行目にデータがある場合、
且つ以下のサンプルデータのC列に0以外の数字が2つ以上ない場合、
エラーが発生します。

import pandas as pd import io csv_data = ''' A,B,C 9/1, 0, 11,11 9/2, 0, 0,11 9/3 ,0 ,0,11 9/4, 10, 0,21 9/5, 0, 0,21 9/6, 1, 0,22 ''' df = pd.read_csv(io.StringIO(csv_data)) print(df['C'].ne(0).cumsum()) df['計算結果'] = df.groupby(df['C'].ne(0).cumsum(), group_keys=False)\ .apply(lambda x: x['B'] + (x.iloc[0]['C']-x.iloc[0]['B']*(x.iloc[0]['C']>0))) print(df)

以下エラー内容

python

1ValueError: Expected a 1D array, got an array with shape (6, 6)

エラーは、サンプルデータの一番下に9/7,1,25を追加すると改善されます。

どなたかご知見があれば教えていただきたく投稿しました。
お忙しいところ恐れ入りますが、ご知見のある方、ご協力いただければ幸いです。

以上、よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

グループがひとつしかないときのGroupby.apply()の挙動についての質問は、stackoverflowでも見つかります。
https://stackoverflow.com/questions/62102565/
https://stackoverflow.com/questions/66837704/

対策としてはgroupbyにsqueeze=Trueを追加するとありますが、現在このオプションはdeprecatedになっているので、applyの結果をsqueezeするのが最新の対処のようです。
(https://github.com/pandas-dev/pandas/issues/32380)

python

1df['計算結果'] = (df.groupby(...) 2 .apply(lambda x: ...) 3 .squeeze())

もしくは、applyを使わなければよいので、applyのlambdaの中でやっている処理を外に出してしまって、groupbyのあとはcumsumだけするようにすれば、シンプルに書くことができます。

python

1grp = df['C'].ne(0).cumsum() 2df['計算結果'] = df['C'].where(df['C'] != 0, df['B']).groupby(grp).cumsum()

投稿2022/09/27 03:11

bsdfan

総合スコア4571

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

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

karakarakarappo

2022/09/27 05:38

bsdfanさん コメントいただきありがとうございます。 グループが1つだけしかない場合のエラーへの対処方法がよく分かりました。 後ほど自分で見返してわかりやすいように、applyのlambdaの中でやっている処理を外に出して対処することにしました。 ご協力いただきありがとうございました!
guest

0

python

1import pandas as pd 2import io 3 4csv_data = ''' 5A,B,C 69/1,0,11 79/2,0,0 89/3,0,0 99/4,10,0 109/5,0,0 119/6,1,0 129/7,1,25 13''' 14df = pd.read_csv(io.StringIO(csv_data)) 15 16# 17df['計算結果'] = df.groupby(df['C'].ne(0).cumsum(), group_keys=False)\ 18 .apply(lambda x: x['B'].mask(x['C'] != 0, x['C']).cumsum()) 19 20print(df)
ABC計算結果
9/101111
9/20011
9/30011
9/410021
9/50021
9/61022
9/712525

投稿2022/09/26 16:09

melian

総合スコア19803

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

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

karakarakarappo

2022/09/27 05:42

コメントありがとうございます。 .maskでも対応できそうでした、違うパターンでエラーが発生した場合はこちらも試してみようと思います。 ご協力ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問