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

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

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

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

データマイニング

データマイニングは、購買履歴やクレジットカードの利用履歴、電話の通話履歴など企業にある大量のデータを解析して、その中に隠れたパターンやルールを探し出す技術です。DMと略されることもあります。

Q&A

解決済

1回答

4298閲覧

pandas: 加重平均を用いたデータ処理

Seorie

総合スコア1

pandas

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

データマイニング

データマイニングは、購買履歴やクレジットカードの利用履歴、電話の通話履歴など企業にある大量のデータを解析して、その中に隠れたパターンやルールを探し出す技術です。DMと略されることもあります。

0グッド

0クリップ

投稿2020/12/20 01:15

編集2020/12/21 13:29

Python Pandasでのデータ処理の質問です。
以下のようなDataFrameに対して、

df1

ABC
100
010
00-1
-100
010
0-10

以下のようなDataFrameを返す処理をさせたいと考えています。
df2

ABC
0.50.50.5
0.750.50.5
0.750.750.5
0.750.750.25
0.3750.750.25
0.3750.8750.25

df1とdf2ともに行方向に時系列データです。
df1が問題A,B,Cに対しての正解不正解を表しており、df2がA,B,Cに対する習熟度のイメージです。
df2の先頭行は0.5として初期化しています。

処理の内容としては、df1の各行の値(1:正解, -1:不正解, 0.5:未出題)に対して、
df2の次の行のスコアが更新される、というものです。
スコアの更新方法は、正解ならば直前のスコアの0.5倍に0.5を加算し、不正解ならば直前のスコアを0.5倍するだけ、という仕様です。

df2の各値は加重平均で表すことができ、例えば2回正解したときのdf2の値は、
0.75 = 0.5 * 0.5 + 0.5
0.875 = 0.5 * 0.75 + 0.5
= 0.5 * (0.5 * 0.5 + 0.5) + 0.5
= 0.5^2 * 0.5 + 0.5 * 0.5 + 0.5
となります。

単純な加重平均ならば

np.average(df1, weights=hoge)

で算出できると思うのですが、上記のようなケースだとどのように記述すれば高速に処理できるのでしょうか。

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

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

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

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

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

meg_

2020/12/20 02:46

> df1の各行の値(1:正解, -1:不正解) 「0」は何でしょうか?
Seorie

2020/12/20 02:54

0は出題されていないので無回答を表します。説明不足でした。 df1の冒頭3行は 問題1がAで正解、問題2がBで正解、問題3がCで不正解 の意味です。
meg_

2020/12/20 06:14

> 説明不足でした。 質問は編集できますので追記しましょう。 また、df2の1行目が「0.5」なのはどういう計算ですか?
Seorie

2020/12/20 06:31 編集

0.5はA,B,Cに対する習熟度として初期値0.5を割り当てています。
meg_

2020/12/20 11:10

質問は編集できますので追加の情報は質問に追記しましょう。
meg_

2020/12/20 11:50

> 正解ならば直前のスコアの0.5倍に1を加算し、 > 0.75 = 0.5 * 0.5 + 0.5 説明文の「1を加算し」は間違いでしょうか?
Seorie

2020/12/21 13:28

>説明文の「1を加算し」は間違いでしょうか? 0.5の誤りでした。 質問も編集したいと思います。
guest

回答1

0

ベストアンサー

もし加重平均にこだわらないのであれば、以下のように素直に計算してはいかがですか。
あまり凝った計算をやると却って遅くなることがあるので、これぐらいでも十分だと思います。

python

1import pandas as pd 2import numpy as np 3 4def learning_level(df): 5 a1 = df.values 6 rows, columns = df.shape 7 8 a2 = np.zeros((rows + 1) * columns).reshape((rows + 1, columns)) 9 a2[0] = 0.5 10 for i in range(rows): 11 a2[i+1] = np.where (a1[i] != 0, a2[i] / 2.0, a2[i]) 12 a2[i+1] = np.where (a1[i] == 1, a2[i+1] + 0.5, a2[i+1]) 13 return pd.DataFrame(a2, columns = df.columns) 14 15if __name__ == '__main__': 16 17 df1 = pd.DataFrame({'A': [1,0,0,-1,0,0], 18 'B': [0,1,0,0,1,-1], 19 'C': [0,0,-1,0,0,0] }) 20 df2 = learning_level(df1) 21 print(df2) 22

実行すると以下のようになります。

linux

1$ python learning_level.py 2 A B C 30 0.500 0.5000 0.50 41 0.750 0.5000 0.50 52 0.750 0.7500 0.50 63 0.750 0.7500 0.25 74 0.375 0.7500 0.25 85 0.375 0.8750 0.25 96 0.375 0.4375 0.25

df2の縦を1行増やしてあるのは、df1の最終行の成績を反映させるためです。

投稿2020/12/20 08:27

ppaul

総合スコア24670

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

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

Seorie

2020/12/21 13:30

ありがとうございます。素直にforループで処理することになるのですね、参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問