【エラーメモ】qcut関数のエラーValueError: Bin edges must be unique
プログラムの実装時に遭遇したエラーを『エラーメモ』という形で残します。 簡易的にしかまとめませんが、誰かのお役に立てれば幸いです。
今回は、分位分析を実施する際(ビ二ング処理)に用いられる、pandasのqcut関数の利用時に遭遇したエラーです。
qcut関数とは?
下記サイトが大変参考になります。 いずれ自分でもまとめようと思っておりますので、お待ち下さい。
以下、簡単な使用例です。 数列[1,2,3,4,5]を3つに分割することを考えます。
import pandas as pd data = pd.DataFrame([1,2,3,4,5]) data.columns = ['val'] data['RNK'] = pd.qcut(data['val'], 3, labels=['Q1', 'Q2', 'Q3'])
特に問題なく、data
を3つに分割できました。
index | val | RNK |
---|---|---|
0 | 1 | Q1 |
1 | 2 | Q1 |
2 | 3 | Q2 |
3 | 4 | Q3 |
4 | 5 | Q3 |
参考サイト
エラー『Bin edges must be unique』とは?
どんなエラー?原因は?
数列[1,1,1,1,2]のような重複のある数列を、3つに分割することを考えます。
すると、次のようにBin edges must be unique
のエラーが発生します。
import pandas as pd data = pd.DataFrame([1,1,1,1,2]) data.columns = ['val'] data['RNK'] = pd.qcut(data['val'], 3, labels=['Q1', 'Q2', 'Q3']) #ValueError: Bin edges must be unique: array([1., 1., 1., 2.]). #You can drop duplicate edges by setting the 'duplicates' kwarg
エラーの原因は、図のように重複のある数列部分に、分位点を設定できないこと、だと思われます。
解決策は?
以下のサイト等を参考に簡単な解決策だけ、まとめました。 難しそうな方法もあるみたいなので、時間を見つけて追加します。(いつか)
①:発生順にランクづけする
rank(method='first')
を用いて、ランクづけを行います。
重複がある場合も出現順にランクづけをするので、分割することが可能です。
import pandas as pd data = pd.DataFrame([1,1,1,1,2]) data.columns = ['val'] data['RNK'] = pd.qcut(data['val'].rank(method='first'), 3, labels=['Q1', 'Q2', 'Q3'])
以下のように、重複ある数列も、発生順に分割できます。
index | val | RNK |
---|---|---|
0 | 1 | Q1 |
1 | 1 | Q1 |
2 | 1 | Q2 |
3 | 1 | Q3 |
4 | 2 | Q3 |
②:ノイズを加え、重複を解消する
重複のある数列にノイズを加え、重複を解消します。
今回は、平均0標準偏差1e-3の正規分布から発生したノイズを加えます。
import numpy as np import pandas as pd data = pd.DataFrame([1,1,1,1,2]) eps = 1e-3 data = data + np.random.normal(0, eps, data.shape) data.columns = ['val'] data['RNK'] = pd.qcut(data['val'], 3, labels=['Q1', 'Q2', 'Q3'])
以下のように、重複ある数列も分割できます。
index | val | RNK |
---|---|---|
0 | 0.999253 | Q1 |
1 | 1.001692 | Q3 |
2 | 1.000051 | Q2 |
3 | 0.999363 | Q1 |
4 | 2.000191 | Q3 |