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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

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

Q&A

解決済

2回答

1695閲覧

[python]sklearnのSimpleImputerを実行した結果、カラム数が変わってしまった

coffee_break

総合スコア9

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

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

0グッド

0クリップ

投稿2020/01/18 15:03

かなり曖昧な質問になってしまい、恐縮ですが、もし知見のある方がいらっしゃいましたらご教示ください。
Nanを含む列を持つX_train(3000,1421)に対して、SimpleImputerで欠損値補完を実施しようとしておりました。
その後、その結果を再度DataFrame型に格納する処理を行いたいです。
そこで以下のように処理を実行しました。

python

1from sklearn.impute import SimpleImputer 2imp = SimpleImputer() 3imp.fit(X_train) 4X_train = pd.DataFrame(imp.transform(X_train), columns=X_train.columns.values)

すると、以下のエラーが出力されました。

python

1ValueError: Wrong number of items passed 1408, placement implies 1421

そのため、処理を分解して追っていったところ、

python

1from sklearn.impute import SimpleImputer 2imp = SimpleImputer() 3imp.fit(X_train) 4imp.transform(X_train).shape★

★の部分で次元を見たところ、3000,1408となっていました。
なので、エラーの原因としては、SimpleImputerで欠損値補完を行ったあとのnparrayのカラム数が1408である一方、DataFrame型に格納する際のindexとして指定しているカラム数は1421なので、不一致としてエラーとなっているものと考えています。

そこで以下についてご教示いただきたいです。
「imp.transform(X_train)を行った時に、カラム数が減少する(削除される)のはどういう場合か」

これがわかれば、原因となったカラムを削除した状態でDataFrameに格納(1408列として)できると考えています。

お手数おかけしますがよろしくお願いします

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

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

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

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

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

guest

回答2

0

リファレンスには

Notes

Columns which only contained missing values at fit are discarded upon transform if strategy is not “constant”.
sklearn.impute.SimpleImputer — scikit-learn 0.22.1 documentation

という記述があり、何が起きたのかを物語ってくれています。

X_train.isnull().all(axis=0)のようにすれば全列NaNの列はわかるのでそれを使って対処すればいいのかもしれませんが、X_testにも同様の変換を施さないといけないので何かと厄介でしょう。

投稿2020/01/18 16:12

hayataka2049

総合スコア30933

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

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

0

ベストアンサー

これが真の原因かどうかは分かりませんが、全ての値がNaNの列は無くなるようです。

Python

1import pandas as pd 2import numpy as np 3from sklearn.impute import SimpleImputer 4 5imp = SimpleImputer(verbose=1) 6X_train = pd.DataFrame([[np.nan, 2, 3], [np.nan, np.nan, np.nan], [np.nan, 5, 9]]) 7print(X_train) 8# 0 1 2 9#0 NaN 2.0 3.0 10#1 NaN NaN NaN 11#2 NaN 5.0 9.0 12imp.fit(X_train) 13print(imp.transform(X_train)) 14#[[2. 3. ] 15# [3.5 6. ] 16# [5. 9. ]]

SimpleImputer と同じ処理を行う方法として pandasの `DataFrame.fillna()`` がありますが、こちらを使うと問題が解決しそうですが、これでは駄目なのでしょうか。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html

Python

1print(X_train.fillna(X_train.mean())) 2# 0 1 2 3#0 NaN 2.0 3.0 4#1 NaN 3.5 6.0 5#2 NaN 5.0 9.0

投稿2020/01/18 16:05

magichan

総合スコア15898

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

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

hayataka2049

2020/01/18 16:18

変数名からして機械学習の学習データとテストデータなので、おそらく同じようなX_testがあり、こちらもX_trainを埋めるのに使った値で埋める必要があります。SimpleImputerでは何もしなくてもそうなりますが、pandasでいけるでしょうか。 (この辺りの前処理はscikit-learnもpandasも一長一短という印象です。)
magichan

2020/01/19 00:31

1行で書いてはいますが、埋める値を求める処理(X_train.mean())と埋める処理(X_train.fillna())の2つは別の処理ですのでpandasでも fill_value = X_train().mean() #又は pd.concat([X_train,X_test]).mean() X_train = X_train.fillna(fill_value) X_test = X_test.fillna(fill_value) のような対応可能です。(何もしなくてもというのはよくわかりませんが)
hayataka2049

2020/01/19 05:05

なるほど、理解しました。mappingを引数に取れれば問題なさそうです。 > 何もしなくてもというのはよくわかりませんが fitメソッドの実行時に平均値の情報が内部に保持され、transformメソッドではそれが使われます。なので、自然な使い方をすればこの辺りでは問題が起きない・手間もかからないということを指しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問