2017-06-13 13 views
1

私は列に1つのホットエンコーディングを行うことを検討していますが、非常に頻繁なものに対してのみ行います。しきい値Tを下回るものは、すべて自分のカテゴリーに入れられます。頻繁な値のみのホットエンコーディング

私の戦略は、「名前」→「頻度」の辞書を作成することでした。その後、周波数を文字列に変換します。文字列が珍しい場合は、説明的な文字列に置き換える必要があります。好ましくは、私は2つの領域/閾値を有することを望んでいる:「less_common」および「rare」またはそのようなもの。

私の現在の試みです。私はfyiをデバッグするためだけに行を分割しています。 3行目は機能しません。私は、Pythonの3.6とcondaを使用してい

tmp = df["name"].groupby(df["name"]) 
tmp = tmp.agg(['count']) 
tmp['count'] = tmp["count"].apply(lambda x: "Uncommon" if tmp["count"] < 1000.0 else str(x)) 
labelDict = tmp.to_dict() 
#some code? 
df[columnName].replace(labelDict, inplace=True) 
pd.get_dummies(df, columns=['name']) 

エラー:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

いくつかの例示的な入力(他の列がある): 名前は=、、、、B、B、 B、C、C、D

これは

name | count 
a | 4 
b | 3 
c | 2 
d | 1 

Let's say T is =<2 
dict: 
a->4, b->3, c->"Uncommon", d->"Uncommon" 

Remap dict to use the original values if name is numeric: 
a->"a", b->"b", c->"Uncommon", d->"Uncommon" 

As one hot: 
date | id | name_a | name_b | name_Uncommon 
... | ...| 1  | 0  | 0 
... 

現在のlibのバージョン次のようになります。

['alabaster==0.7.10', 'anaconda-client==1.6.3', 'anaconda-navigator==1.6.2', 'anaconda-project==0.6.0', 'appnope==0.1.0', 'appscript==1.0.1', 'asn1crypto==0.22.0', 'astroid==1.4.9', 'astropy==1.3.2', 'babel==2.4.0', 'backports.shutil-get-terminal-size==1.0.0', 'beautifulsoup4==4.6.0', 'bitarray==0.8.1', 'blaze==0.10.1', 'bleach==1.5.0', 'bokeh==0.12.5', 'boto==2.46.1', 'bottleneck==1.2.1', 'branca==0.2.0', 'cffi==1.10.0', 'chardet==3.0.3', 'chest==0.2.3', 'click==6.7', 'cloudpickle==0.2.2', 'clyent==1.2.2', 'colorama==0.3.9', 'conda==4.3.21', 'configobj==5.0.6', 'contextlib2==0.5.5', 'cryptography==1.8.1', 'cycler==0.10.0', 'cython==0.25.2', 'cytoolz==0.8.2', 'dask==0.14.3', 'datashape==0.5.4', 'decorator==4.0.11', 'dill==0.2.6', 'distributed==1.16.3', 'docutils==0.13.1', 'entrypoints==0.2.2', 'et-xmlfile==1.0.1', 'fastcache==1.0.2', 'flask-cors==3.0.2', 'flask==0.12.2', 'folium==0.3.0', 'gevent==1.2.1', 'greenlet==0.4.12', 'h5py==2.7.0', 'heapdict==1.0.0', 'html5lib==0.9999999', 'idna==2.5', 'imagesize==0.7.1', 'ipykernel==4.6.1', 'ipython-genutils==0.2.0', 'ipython==5.3.0', 'ipywidgets==6.0.0', 'isort==4.2.5', 'itsdangerous==0.24', 'jdcal==1.3', 'jedi==0.10.2', 'jinja2==2.9.6', 'jsonschema==2.6.0', 'jupyter-client==5.0.1', 'jupyter-console==5.1.0', 'jupyter-core==4.3.0', 'jupyter==1.0.0', 'keras==2.0.4', 'lazy-object-proxy==1.2.2', 'llvmlite==0.18.0', 'locket==0.2.0', 'lxml==3.7.3', 'mako==1.0.6', 'markdown==2.2.0', 'markupsafe==0.23', 'matplotlib==2.0.2', 'mistune==0.7.4', 'mpmath==0.19', 'msgpack-python==0.4.8', 'multipledispatch==0.4.9', 'navigator-updater==0.1.0', 'nbconvert==5.1.1', 'nbformat==4.3.0', 'networkx==1.11', 'nltk==3.2.3', 'nose==1.3.7', 'notebook==5.0.0', 'numba==0.33.0', 'numexpr==2.6.2', 'numpy==1.12.1', 'numpydoc==0.6.0', 'odo==0.5.0', 'olefile==0.44', 'openpyxl==2.4.7', 'packaging==16.8', 'pandas==0.20.1', 'pandocfilters==1.4.1', 'partd==0.3.8', 'pathlib2==2.2.1', 'patsy==0.4.1', 'pep8==1.7.0', 'pexpect==4.2.1', 'pickleshare==0.7.4', 'pillow==4.1.1', 'pip==9.0.1', 'ply==3.10', 'prompt-toolkit==1.0.14', 'protobuf==3.3.0', 'psutil==5.2.2', 'ptyprocess==0.5.1', 'py==1.4.33', 'pyasn1==0.2.3', 'pycosat==0.6.2', 'pycparser==2.17', 'pycrypto==2.6.1', 'pycurl==7.43.0', 'pyflakes==1.5.0', 'pygments==2.2.0', 'pygpu==0.6.4', 'pylint==1.6.4', 'pyodbc==4.0.16', 'pyopenssl==17.0.0', 'pyparsing==2.1.4', 'pytest==3.0.7', 'python-dateutil==2.6.0', 'pytz==2017.2', 'pywavelets==0.5.2', 'pyyaml==3.12', 'pyzmq==16.0.2', 'qtawesome==0.4.4', 'qtconsole==4.3.0', 'qtpy==1.2.1', 'redis==2.10.5', 'requests==2.14.2', 'rope-py3k==0.9.4.post1', 'scikit-image==0.13.0', 'scikit-learn==0.18.1', 'scipy==0.19.0', 'seaborn==0.7.1', 'setuptools==27.2.0', 'simplegeneric==0.8.1', 'singledispatch==3.4.0.3', 'six==1.10.0', 'snowballstemmer==1.2.1', 'sockjs-tornado==1.0.3', 'sortedcollections==0.5.3', 'sortedcontainers==1.5.7', 'sphinx==1.5.6', 'spyder==3.1.4', 'sqlalchemy==1.1.9', 'statsmodels==0.8.0', 'sympy==1.0', 'tables==3.3.0', 'tblib==1.3.2', 'tensorflow==1.2.0rc1', 'terminado==0.6', 'testpath==0.3', 'tflearn==0.3.1', 'theano==0.9.0', 'toolz==0.8.2', 'tornado==4.5.1', 'traitlets==4.3.2', 'unicodecsv==0.14.1', 'wcwidth==0.1.7', 'werkzeug==0.12.2', 'wheel==0.29.0', 'widgetsnbextension==2.0.0', 'wrapt==1.10.10', 'xgboost==0.6', 'xlrd==1.0.0', 'xlsxwriter==0.9.6', 'xlwings==0.10.4', 'xlwt==1.2.0', 'zict==0.1.2'] 

私は関連する解決策を見つけたことを認めますが、私のニーズに合わせて修正する方法は明確ではありません。問題は、{a、b、c、...}の値を持つ「最初の」列と、値が{a、b、c、 、...}これらの列を値でラベル付けします。私は名前の衝突があります。 Pandas One hot encoding: Bundling together less frequent categories

答えて

2

df

np.random.seed([3,1415]) 
df = pd.DataFrame(dict(
     name=np.random.choice(
      list('abcdefghij'), 1000, 
      p=np.arange(10, 0, -1)/55 
     ) 
    )) 
threshold = 60 
counts = df.name.value_counts() 
counts 

a 197 
b 166 
c 139 
d 119 
f 107 
e 105 
g  72 
h  53 
i  27 
j  15 
Name: name, dtype: int64 

その後replacepd.get_dummies

repl = counts[counts <= threshold].index 
print(pd.get_dummies(df.name.replace(repl, 'uncommon'))) 

    a b c d e f g uncommon 
0 0 0 1 0 0 0 0   0 
1 0 0 1 0 0 0 0   0 
2 0 0 1 0 0 0 0   0 
3 0 0 1 0 0 0 0   0 
4 0 0 1 0 0 0 0   0 
5 1 0 0 0 0 0 0   0 
6 0 0 0 0 0 0 1   0 
7 0 0 0 0 0 1 0   0 
8 0 0 0 0 0 1 0   0 
9 0 0 0 0 0 1 0   0 
10 0 0 0 0 0 0 0   1 
11 0 0 0 0 0 0 1   0 
12 0 0 0 0 0 0 1   0 
13 0 0 0 0 0 0 0   1 
14 0 0 0 0 1 0 0   0 
15 1 0 0 0 0 0 0   0 
16 1 0 0 0 0 0 0   0 
17 0 1 0 0 0 0 0   0 
0

サンプルデータフレームを考えてみましょうここに私が思い付いたソリューションです。基本的に、私はインデックスが何であるか、それをどのように変更するかを知る必要がありました。条件付きの複合フィルタリングまたはマッピングが機能していないため、不明なエラーメッセージが表示されました。私は<T1のインデックスを作成し、次に<T2を作成しました。 > .T2と< .T1の組み合わせを取得するには(私は奇妙な書式設定のバグのためにピリオドを追加しましたが)、私は設定の違いを行うだけでした。そして、魔法のように、インデックス(値のシーケンス)は目標値をrare/uncommonに置き換え、get_dummiesはone-hotエンコードを行います。

また、df.indexの使用に関するヒントについては、piRSquaredに感謝したいと思います。

def onehot2(df, threshold_uncommon, threshold_rare, column, prefix, normalize=False): 
    freqencies = df[column].value_counts(sort=False, normalize=normalize) 
    idx1 = freqencies[freqencies < threshold_uncommon].index 
    idx2 = freqencies[freqencies < threshold_rare].index 
    idx1 = idx1.difference(idx2) 
    tmp = df 
    tmp[column] = df[column].replace(idx1, 'uncommon') if idx1.shape[0] > 0 else df 
    tmp[column] = tmp[column].replace(idx2, 'rare') if idx2.shape[0] > 0 else tmp 
    d = pd.get_dummies(tmp, columns=[column], prefix=prefix, dummy_na=True)# 
    return d 

def onehot(df, threshold, column, prefix, normalize=False): 
    freqencies = df[column].value_counts(sort=False, normalize=normalize) 
    idx = freqencies[freqencies < threshold].index 
    tmp = df 
    if idx.shape[0] > 0: 
     tmp[column] = df[column].replace(idx, 'uncommon') 
    else: 
     tmp = df 
    d = pd.get_dummies(tmp, columns=[column], prefix=prefix, dummy_na=True)# 
    return d 
関連する問題