Python ColumnTransformer SettingWithCopyWarning -- python フィールド と pandas フィールド と numpy フィールド と dataframe フィールド と scikit-learn フィールド 関連 問題

Python ColumnTransformer SettingWithCopyWarning












1
vote

問題

日本語

Scikit-Learn ColumnTranstransformer を使用してデータフレームを使用して、データフレームに変換を適用する場合は、設定を受けている問題を抱えています。あれは。

これは私のコードです。

<事前> <コード> import pandas as pd import numpy as np from sklearn.compose import ColumnTransformer from sklearn.preprocessing import FunctionTransformer import warnings warnings.filterwarnings("always") def filling_nan(frame): """Fills columns that have null values with zeros.""" frame.fillna(0, inplace=True) return frame def as_is(frame): """Returns the DataFrame as it is.""" return frame np.random.seed(1337) df = pd.DataFrame(data=np.random.random(size=(5,5)), columns=list('ABCDE')) df = df.applymap(lambda x: np.nan if x<0.15 else x) # Set a few numbers in the dataframe to NaN. print(df)

これは元のデータフレームのようなものです...

<事前> <コード> A B C D E 0 0.262025 0.158684 0.278127 0.459317 0.321001 1 0.518393 0.261943 0.976085 0.732815 NaN 2 0.386275 0.628501 NaN 0.983549 0.443225 3 0.789558 0.794119 0.361262 0.416104 0.584258 4 0.760172 0.187808 0.288167 0.670219 0.499648

次に、ColumnTransformerとで列名ではなくのインデックスを指定します。

<事前> <コード> step_filling_nans = ('filling_nans', FunctionTransformer(filling_nan, validate=False), [2, 4]) step_as_is = ('as_is', FunctionTransformer(as_is, validate=False), [0, 1, 3])

その後ColumnTransformerを作成します...

<事前> <コード> trans = ColumnTransformer( transformers=[ step_filling_nans , step_as_is # I could pass 'passthrough' to the remainder keyword instead of doing this step. ], remainder='drop')

最後に、ColumnTransformerをデータフレームに適用する結果を印刷します。

<事前> <コード> print(trans.fit_transform(df))

これは変換の出力です。 ColumnTransformerはそれぞれ(それぞれ列 'C'および 'E'を持つ)と同じようにnumpy配列を返しますが、私が settingcopy 警告を受けている理由はわかりません。

<事前> <コード> [[0.27812652 0.32100054 0.26202468 0.15868397 0.45931689] [0.97608528 0. 0.51839282 0.26194293 0.73281455] [0. 0.44322487 0.38627507 0.62850118 0.98354861] [0.36126157 0.58425813 0.78955834 0.79411858 0.41610394] [0.28816715 0.49964826 0.76017177 0.18780841 0.67021886]] /bigdisk0/users/belladam/.conda/envs/day_zero_retention/lib/python3.6/site-packages/pandas/core/frame.py:3787: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy downcast=downcast, **kwargs)

filling_nan()関数をわずかに変更することで修正することができましたが、それが修正されている理由はわかりません。

<事前> <コード> def filling_nan(frame): """Fills columns that have null values with zeros.""" frame = frame.fillna(0) return frame

ColumnTransformerを使用する以外の結果を再現できませんので、それが何かでやるべきことだったか疑問に思いましたか?

英語

I'm having a problem where I'm receiving a SettingWithCopyWarning when applying transformations to a DataFrame using a scikit-learn ColumnTransformer, and I'm not sure why that is.

This is my code.

import pandas as pd import numpy as np from sklearn.compose import ColumnTransformer from sklearn.preprocessing import FunctionTransformer  import warnings warnings.filterwarnings("always")  def filling_nan(frame):     """Fills columns that have null values with zeros."""     frame.fillna(0, inplace=True)     return frame  def as_is(frame):     """Returns the DataFrame as it is."""     return frame  np.random.seed(1337) df = pd.DataFrame(data=np.random.random(size=(5,5)), columns=list('ABCDE')) df = df.applymap(lambda x: np.nan if x<0.15 else x) # Set a few numbers in the dataframe to NaN.  print(df) 

This is what the original DataFrame looks like...

          A         B         C         D         E 0  0.262025  0.158684  0.278127  0.459317  0.321001 1  0.518393  0.261943  0.976085  0.732815       NaN 2  0.386275  0.628501       NaN  0.983549  0.443225 3  0.789558  0.794119  0.361262  0.416104  0.584258 4  0.760172  0.187808  0.288167  0.670219  0.499648 

Then I create the steps in the ColumnTransformer and I specify the index of the column rather than the column name.

step_filling_nans = ('filling_nans', FunctionTransformer(filling_nan, validate=False), [2, 4]) step_as_is = ('as_is', FunctionTransformer(as_is, validate=False), [0, 1, 3]) 

Then I create the ColumnTransformer...

trans = ColumnTransformer(     transformers=[         step_filling_nans         , step_as_is # I could pass 'passthrough' to the remainder keyword instead of doing this step.     ], remainder='drop') 

Finally, I print the result of the applying the ColumnTransformer to my DataFrame.

print(trans.fit_transform(df)) 

This is the output of the transformations. The ColumnTransformer returns a numpy array as expected (with columns 'C' and 'E' first and second respectively), but I don't understand why I'm receiving the SettingWithCopy warning.

[[0.27812652 0.32100054 0.26202468 0.15868397 0.45931689]  [0.97608528 0.         0.51839282 0.26194293 0.73281455]  [0.         0.44322487 0.38627507 0.62850118 0.98354861]  [0.36126157 0.58425813 0.78955834 0.79411858 0.41610394]  [0.28816715 0.49964826 0.76017177 0.18780841 0.67021886]]  /bigdisk0/users/belladam/.conda/envs/day_zero_retention/lib/python3.6/site-packages/pandas/core/frame.py:3787: SettingWithCopyWarning:  A value is trying to be set on a copy of a slice from a DataFrame  See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy   downcast=downcast, **kwargs)  

I have managed to fix it by changing the filling_nan() function slightly, but I don't understand why that fixes it.

def filling_nan(frame):     """Fills columns that have null values with zeros."""     frame = frame.fillna(0)     return frame 

I've been unable to reproduce the result outside of using a ColumnTransformer so was wondering if it was something to do with that?

</div
              

回答リスト

0
 
vote
vote
ベストアンサー
 

私は ColumnTransformer がこのように動作することが異なるため、異なる列に関連する並列変換を実行できるため、このように動作します。 sklearnを見ることができます。並列化を使用したい場合は、同じオブジェクト(同じメモリの場所)で動作しても安全ではありません。

inplace を使用しないようにして、実際には元のオブジェクトのコピーに取り組んでおり、問題は解決します。

<事前> <コード> def filling_nan(frame): """Fills columns that have null values with zeros.""" frame = frame.fillna(0) return frame def filling_nan_inplace(frame): """Fills columns that have null values with zeros.""" frame.fillna(0, inplace=True) return frame print(id(df)) print(id(filling_nan_inplace(df))) print(id(filling_nan(df)))

出力:

<事前> <コード> 2088604584760 2088604584760 2088604583304
 

I believe ColumnTransformer behaves this way because it is capable of running in parallel different transformations related to different columns. You can take a look at the sklearn code itself here, at line 448. If you want to use parallelization then it is not really safe to work on the same object (same memory location).

By avoiding using inplace, you are actually working on copy of the original object, and this settles the problem:

def filling_nan(frame):     """Fills columns that have null values with zeros."""     frame = frame.fillna(0)     return frame  def filling_nan_inplace(frame):     """Fills columns that have null values with zeros."""     frame.fillna(0, inplace=True)     return frame  print(id(df)) print(id(filling_nan_inplace(df))) print(id(filling_nan(df))) 

output:

2088604584760 2088604584760 2088604583304 
</div
 
 

関連する質問

8  scikit-learn roc_auc_score()は正確さの値を返します  ( Scikit learn roc auc score returns accuracy values ) 
次の方法を使用して、<コード> sklearn.metrics.roc_auc_score を使用してROC曲線の下の領域を計算しようとしています。 <事前> <コード> roc_auc = sklearn.metrics.roc_auc_score(actu...

2  XGBoost Pythonのテストデータの予測中にエラーが発生しました  ( Error while predicting test data in xgboost python ) 
XGBoost Pythonを使用してテキストの分類を実行しています 下記は私が検討しているTrainesetです。 <事前> <コード> itemid description ...

0  Pipeline + StandardScaler + OHE + CLF + GRIDSearchCV + ColumnTranFormer  ( Pipeline standardscaler ohe clf gridsearchcv columntranformer ) 
私のLILプロジェクトのためのPipeline + StandardScaler + OHE + CLF + GRIDSearchCV + ColumnTranFormerを使用してデータモデリングしようとしていました。 私はコードを除いてちょうど罰金を尽くす...

4  Sklearnのロジスティック回帰機能  ( Logistic regression function on sklearn ) 
Sklearnからロジスティック回帰を学んで、これに渡って来ました: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.logisticRegression.htmor...

3  CATACORICALと見なす必要がある文字列を使用したSKLEARN DecisionTreeCassifier  ( Sklearn decisiontreeclassifier using strings that should be considered categoric ) 
<コード> sklearn.tree.DecisionTreeClassifier を訓練しています。 pandas.core.frame.DataFrame で始まります。このデータフレームの列の一部は、実際にカテゴリカルにする必要がある文字列です。たと...

1  Python - クラスタプロットチャートからリストを取得する方法  ( Python how to get list from cluster plot chart ) 
k平均クラスタリング法を使用するためにSklearnを使用しています。しかし、問題は、クラスタプロットチャートからリストを取得できます。私のコードは以下のようなです <事前> <コード> coord.service5 実際に私はすでにコードを手に入れ...

0  AttributeError: 'GaussianMixture'オブジェクトにはPythonに属性 'covars_'がありません  ( Attributeerror gaussianmixture object has no attribute covars in python ) 
これはこの link と下記に示すように、 <事前> <コード> from matplotlib.patches import Ellipse def draw_ellipse(position, covariance, ax=None, **kwargs...

1  カテゴリカルフィーチャカテゴリ特徴と非カテゴリカルフィーチャに回帰する方法  ( How to make regression with categorical and non categorical features ) 
複数の機能がある場合は、Sklearnで回帰をする正しい方法は何がありますが、いくつかの機能はカテゴリカーであり、いくつかは何ですか? 私は 'columntransformer'を試していましたが、私がそれをやっているのはよくわからない: <事前> <コード...

4  Scikit - OpenMP libsvmを学びました  ( Scikit learn openmp libsvm ) 
Scikit-Learn SVCを使用してデータを分類しています。トレーニングパフォーマンスを向上させたいのですが。 clf = svm.svc(cache_size = 4000、確率= true、verbose = true) libsvmとli...

2  ターミナルで動作していても、インポート中のPycharmエラー  ( Pycharm error while importing even though it works in the terminal ) 
パッケージTensorflowとScikit_Learnとそのすべての依存関係をインストールしました。 Python 2.7.6または2.7.10(両方とも試してみた)を使用してターミナルでそれらをインポートしてみるとうまく機能します。ただし、Pycharmを...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有