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

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

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

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

pandas

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

Q&A

解決済

2回答

940閲覧

pythonでデータの加工・整形の仕方でわかりません

onosan

総合スコア62

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

pandas

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

0グッド

1クリップ

投稿2022/01/02 13:47

以下のようなデータがあります。
施設と個人コードの2つで個人を特定できます。
年月Noは実際は年月なのですが、時系列の流れが分かるように数値にしています。(数字が大きいほど、あとの月)
ステージはその個人のある状況のステージです。(0から5まで6段階あります。)
(施設、個人コード、年月No、ステージの順番でソートを昇順にかけています。)
報酬というカラムを作成したいと思います。これは、ある個人がある年月でステージがアップした時、
そのアップした大きさに応じて、報酬を与えたいと考えています。
例えば、0→1なら後の数値1と差額の1をかけて1、1→2であれば、後の数値の2に差額の1をかけて2、
3→5であれば、後の数値の5と差額の2をかけて10のようにしたいと思っております。
数値に変化がなかったり、値が決まらなければ0にしたいと考えております。
下記のdataframeを作成した段階で、for文を使っても、後のインデックスを認識させることができず、

Python

1for i,n in enumerate(zip(df["施設"].values,df["個人コード"].values,df["年月No"].values,df["ステージ"].values)): 2 print(i,n) 3 4#とか 5for i,v in enumerate(df.values): 6 print(i,v[0],v[1],v[2],v[3])

などとやったのですが、インデックスが先の状態のことをどのように記憶させるのかわからず、手が止まってしまいました。
報酬のカラムを作成するのに、お知恵をいただけないでしょうか。
何卒よろしくお願い申し上げます。

施設個人コード年月Noステージ
1022965226724210
1022965226724221
1022965226724231
1022965226724241
1022965226724252
1022965226724262
1022965226724272
1022965226724282
1022965226724293
10229652267242103
10229652267242113
10229652267242123
1022980019800013
1022980019800023
1022980019800033
1022980019800043
1022980019800054
1022980019800064
1022980019800074
1022980019800084
1022980019800095
10229800198000105

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

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

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

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

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

meg_

2022/01/02 14:13

ステージが下がることはありますか? > for文を使っても、後のインデックスを認識させることができず、 素直に前のデータとの差分を確認して操作するようなコードにしてはどうでしょうか?
guest

回答2

0

python

1df['報酬'] = df.groupby(['施設', '個人コード'])['ステージ'].diff().fillna(0).astype(int) * df['ステージ'] 2 3print(df) 4 5# 6 施設 個人コード 年月No ステージ 報酬 70 10229652 267242 1 0 0 81 10229652 267242 2 1 1 92 10229652 267242 3 1 0 103 10229652 267242 4 1 0 114 10229652 267242 5 2 2 125 10229652 267242 6 2 0 136 10229652 267242 7 2 0 147 10229652 267242 8 2 0 158 10229652 267242 9 3 3 169 10229652 267242 10 3 0 1710 10229652 267242 11 3 0 1811 10229652 267242 12 3 0 1912 10229800 198000 1 3 0 2013 10229800 198000 2 3 0 2114 10229800 198000 3 3 0 2215 10229800 198000 4 3 0 2316 10229800 198000 5 4 4 2417 10229800 198000 6 4 0 2518 10229800 198000 7 4 0 2619 10229800 198000 8 4 0 2720 10229800 198000 9 5 5 2821 10229800 198000 10 5 0

投稿2022/01/02 15:04

melian

総合スコア20655

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

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

onosan

2022/01/03 01:20

迅速にご回答いただき、ありがとうございます。2つ回答をいただき、両方ともベストアンサーにしたかったのですが、2つベストにできずに残念です。diff()という関数があることを恥ずかしながら知りませんでした。とてもためになりました。ありがとうございます。感謝いたします。
guest

0

ベストアンサー

こういう感じです。

python

1>>> print(df) 2 施設 個人コード 年月No ステージ 30 10229652 267242 1 0 41 10229652 267242 2 1 52 10229652 267242 3 1 63 10229652 267242 4 1 74 10229652 267242 5 2 85 10229652 267242 6 2 96 10229652 267242 7 2 107 10229652 267242 8 2 118 10229652 267242 9 3 129 10229652 267242 10 3 1310 10229652 267242 11 3 1411 10229652 267242 12 3 1512 10229800 198000 1 3 1613 10229800 198000 2 3 1714 10229800 198000 3 3 1815 10229800 198000 4 3 1916 10229800 198000 5 4 2017 10229800 198000 6 4 2118 10229800 198000 7 4 2219 10229800 198000 8 4 2320 10229800 198000 9 5 2421 10229800 198000 10 5 25>>> 26>>> df['報酬'] = (df['ステージ'] * (df['ステージ'] - df['ステージ'].shift())).where((df['施設']==df['施設']) & (df['個人コード']==df['個人コード']), 0).fillna(0).astype(int) 27>>> 28>>> print(df) 29 施設 個人コード 年月No ステージ 報酬 300 10229652 267242 1 0 0 311 10229652 267242 2 1 1 322 10229652 267242 3 1 0 333 10229652 267242 4 1 0 344 10229652 267242 5 2 2 355 10229652 267242 6 2 0 366 10229652 267242 7 2 0 377 10229652 267242 8 2 0 388 10229652 267242 9 3 3 399 10229652 267242 10 3 0 4010 10229652 267242 11 3 0 4111 10229652 267242 12 3 0 4212 10229800 198000 1 3 0 4313 10229800 198000 2 3 0 4414 10229800 198000 3 3 0 4515 10229800 198000 4 3 0 4616 10229800 198000 5 4 4 4717 10229800 198000 6 4 0 4818 10229800 198000 7 4 0 4919 10229800 198000 8 4 0 5020 10229800 198000 9 5 5 5121 10229800 198000 10 5 0

投稿2022/01/02 14:45

ppaul

総合スコア24670

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

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

onosan

2022/01/03 01:23

迅速にご回答いただき、ありがとうございます。2つ回答をいただき、両方ともベストアンサーにしたかったのですが、2つベストにできずに残念です。shift()という関数があることを恥ずかしながらしりませんでした。厳密には、where((df['施設']==df['施設'].shift()) & (df['個人コード']==df['個人コード'].shift()), 0)にしないといけなかったようなのですが、とても勉強になったので、ベストアンサーにさせていただきます。感謝いたします。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問