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

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

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

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

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

Python

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

pandas

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

Q&A

解決済

1回答

1152閲覧

DataFrameにカラム追加をする際に, 追加したいカラム自身の数値を用いて値を返す方法

kakedashi_mk_py

総合スコア2

Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

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

Python

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

pandas

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

0グッド

0クリップ

投稿2020/06/19 02:47

前提・実現したいこと

Python, とくにPandasに関する質問です。
DataFrameにカラム追加をする際に, 追加したいカラム自身の数値を用いて値を返す方法をご教示いただけますと幸いです。

ある特定のアクションを経由するとポイントが加算され, ポイントを利用して購入するとその分が減算されていく, という通帳残高のようなカラムを作りたいのですが, 下記のロジックによって条件分岐が発生するため, それをどのように処理すれば実現したいのようにできるのかが分からず困っております。。

▽ロジック
・action_typeがgetのときは, point_getの値を残高に加算する
・action_typeがpurchaseのときは, point_useの値を残高から減算する
└ただし, 減算した値がマイナスの場合は0を返す
・ユーザーごとにpartitionして上記の処理を繰り返す
└partitionした一番上の行は, action_typeがgetならpoint_getの値を入れ, action_typeがuseのときは残高は0からスタートする

減算した値がマイナスになる理由は, 今回のpoint_getのアクション以外の経由でもポイントを獲得することができるため, ポイント利用額の合計値が獲得したポイントの合計値を上回りうるからです。

実現したいDatFrameとしては下記のような状態です(簡単のため1ユーザーでpartitonした状態にしています)。

import pandas as pd df = pd.DataFrame({ 'action_id':['1', '2', '3', '4', '5', '6', '7', '8'], 'user_id':['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'], 'date':['2020-06-05', '2020-06-06', '2020-06-08', '2020-06-10', '2020-06-11', '2020-06-12', '2020-06-15', '2020-06-20'], 'actoin_type':['get', 'purchase', 'purchase', 'purchase', 'get', 'purchase', 'get', 'purchase'], 'point_get':['500', '0', '0', '0', '300', '0', '200', '0'], 'point_use':['0', '300', '0', '500','0', '250', '0', '150'], 'balance':['500', '200', '200', '0', '300', '50', '250', '100'] }) df

balance以外のカラムは既存のデータベースから引っ張ってこれるので、そのbalanceのカラムを上記のロジックで作成したいです。

発生している問題

新しいカラムを作る際にその自身のカラムを使う...といった処理が具体的にどのようにすれば実現できるものなのか分からずご質問させていただきました。
(駆け出しでして, 具体的にどのような処理が該当するのか分からず検索もままならずでして...)

利用環境

Google Colaboratoryを用いて, Big Queryに格納されている取引データと, ポイント獲得のデータをUNION ALLで結合させることで上記のようなDataFrameを作っています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

たとえば下記のような形ですか? getとuse、場合分けせずに両方いれてみました。

python3

1import pandas as pd 2 3df = pd.DataFrame({ 4 'action_id':['1', '2', '3', '4', '5', '6', '7', '8'], 5 'user_id':['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'], 6 'date':['2020-06-05', '2020-06-06', '2020-06-08', '2020-06-10', '2020-06-11', '2020-06-12', '2020-06-15', '2020-06-20'], 7 'actoin_type':['get', 'purchase', 'purchase', 'purchase', 'get', 'purchase', 'get', 'purchase'], 8 'point_get':['500', '0', '0', '0', '300', '0', '200', '0'], 9 'point_use':['0', '300', '0', '500','0', '250', '0', '150'] 10}) 11blc = [] 12record = 0 13for gt,us in zip(df["point_get"],df["point_use"]): 14 record += int(gt) -int(us) 15 if record < 0: 16 record = 0 17 blc.append(record) 18df["balance"] = pd.DataFrame(blc) 19df

user_id別ver.

python3

1import pandas as pd 2import copy 3dfa = pd.DataFrame({ 4 'action_id':['1', '2', '3', '4', '5', '6', '7', '8'], 5 'user_id':['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'], 6 'date':['2020-06-05', '2020-06-06', '2020-06-08', '2020-06-10', '2020-06-11', '2020-06-12', '2020-06-15', '2020-06-20'], 7 'actoin_type':['get', 'purchase', 'purchase', 'purchase', 'get', 'purchase', 'get', 'purchase'], 8 'point_get':['500', '0', '0', '0', '300', '0', '200', '0'], 9 'point_use':['0', '300', '0', '500','0', '250', '0', '150'] 10}) 11dfb = pd.DataFrame({ 12 'action_id':['1', '2', '3', '4', '5', '6', '7', '8'], 13 'user_id':['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b'], 14 'date':['2020-06-05', '2020-06-06', '2020-06-08', '2020-06-10', '2020-06-11', '2020-06-12', '2020-06-15', '2020-06-20'], 15 'actoin_type':['get', 'purchase', 'purchase', 'purchase', 'get', 'purchase', 'get', 'purchase'], 16 'point_get':['300', '0', '100', '0', '300', '0', '200', '0'], 17 'point_use':['0', '300', '0', '500','0', '250', '0', '150'] 18}) 19df=pd.concat([dfa,dfb]) 20df = df.reset_index(drop=True) 21blc = [] 22for user_id, group in df.groupby("user_id"): 23 record = 0 24 for gt,us in zip(group["point_get"],group["point_use"]): 25 record += int(gt) -int(us) 26 if record < 0: 27 record = 0 28 blc.append(record) 29df["balance"] = pd.DataFrame(blc) 30df

投稿2020/06/19 04:02

編集2020/06/22 04:02
jeanbiego

総合スコア3966

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

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

kakedashi_mk_py

2020/06/22 02:22

回答ありがとうございます。 > ・ユーザーごとにpartitionして上記の処理を繰り返す これを実現したいのですが, これをPythonのfor文で表すとどういったかたちになるのでしょうか? SQLでいうWINDOW句のようなものを想起しています。 OVER (PARTITION BY user_id ORDER BY date, action_id ASC)
kakedashi_mk_py

2020/06/22 02:55 編集

```import pandas as pd df = pd.DataFrame({ 'action_id':['1', '2', '3', '4', '5', '6', '7', '8', '1', '2'], 'user_id':['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b'], 'date':['2020-06-05', '2020-06-06', '2020-06-08', '2020-06-10', '2020-06-11', '2020-06-12', '2020-06-15', '2020-06-20', '2020-06-05', '2020-06-07'], 'actoin_type':['get', 'purchase', 'purchase', 'purchase', 'get', 'purchase', 'get', 'purchase', 'purchase', 'get'], 'point_get':['500', '0', '0', '0', '300', '0', '200', '0', '0', '300'], 'point_use':['0', '300', '0', '500','0', '250', '0', '100', '100', '0'] }) blc = [] record = 0 for gt,us, cnt in zip(df["point_get"],df["point_use"], df['action_id']): record += int(gt) -int(us) if int(cnt) == 1: record = 0 blc.append(record) else: if record < 0: record = 0 blc.append(record) df["balance"] = pd.DataFrame(blc) df こんな感じでuserごとに累計回数のカラム出せば行けそうでした!
jeanbiego

2020/06/22 04:03

action_idでリセットするのは面白いですが、それだとaction1が何であれ0にされてしまいませんか。 別アプローチでやってみたコードを回答欄に追加しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問