Python でデータ クリーニングの技術をマスターする - KDnuggets

Python でデータ クリーニングの技術をマスターする – KDnuggets

ソースノード: 2939047

Python でデータ クリーニングの技術を習得する
著者による画像
 

データ クリーニングは、あらゆるデータ分析プロセスの重要な部分です。 これは、エラーを削除し、欠落しているデータを処理し、データが作業可能な形式であることを確認するステップです。 データセットが適切にクリーニングされていないと、その後の分析が歪んだり、不正確になったりする可能性があります。

この記事では、pandas、numpy、seaborn、matplotlib などの強力なライブラリを使用して、Python でデータ クリーニングを行うためのいくつかの主要なテクニックを紹介します。

データクリーニングの仕組みに入る前に、その重要性を理解しておきましょう。 現実世界のデータは乱雑であることがよくあります。 重複したエントリ、不正または一貫性のないデータ型、欠損値、無関係な特徴、外れ値が含まれる可能性があります。 これらすべての要因は、データ分析時に誤解を招く結論につながる可能性があります。 このため、データ クリーニングはデータ サイエンスのライフサイクルにおいて不可欠な部分となっています。

次のデータ クリーニング タスクについて説明します。
 

Python でデータ クリーニングの技術を習得する
著者による画像

始める前に、必要なライブラリをインポートしましょう。 データ操作には pandas を使用し、視覚化には seaborn と matplotlib を使用します。

日付を操作するために datetime Python モジュールもインポートします。

import pandas as pd
import seaborn as sns
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

まず、データをロードする必要があります。 この例では、pandas を使用して CSV ファイルをロードします。 区切り文字引数も追加します。

df = pd.read_csv('F:KDNuggetsKDN Mastering the Art of Data Cleaning in Pythonproperty.csv', delimiter= ';')

次に、データを検査して、その構造、どのような種類の変数を扱っているか、欠損値があるかどうかを理解することが重要です。 インポートしたデータはそれほど大きくないので、データセット全体を見てみましょう。

# Look at all the rows of the dataframe
display(df)

データセットは次のようになります。

 

Python でデータ クリーニングの技術を習得する
 

いくつかの欠損値があることがすぐにわかります。 また、日付の形式も一貫していません。

次に、info() メソッドを使用して DataFrame の概要を見てみましょう。

# Get a concise summary of the dataframe
print(df.info())

これがコード出力です。

 

Python でデータ クリーニングの技術を習得する
 

列 square_feet のみに NULL 値がないことがわかります。そのため、これを何らかの方法で処理する必要があります。 また、列advertising_dateおよびsale_dateは、日付である必要がありますが、オブジェクトのデータ型です。

列の位置が完全に空です。 それは必要ですか?

これらの問題に対処する方法を紹介します。 まずは不要な列を削除する方法を学びます。

データセットにはデータ分析に不要な列が XNUMX つあるため、それらを削除します。

最初の列は購入者です。 購入者の名前は分析に影響を与えないため、必要ありません。

指定された列名でdrop()メソッドを使用しています。 列を削除することを指定するために、軸を 1 に設定します。 また、既存の DataFrame を変更し、削除された列なしで新しい DataFrame を作成しないように、inplace 引数は True に設定されています。

df.drop('buyer', axis = 1, inplace = True)

削除する XNUMX 番目の列は場所です。 この情報があると便利かもしれませんが、これは完全に空の列なので、そのまま削除しましょう。

最初の列と同じアプローチを採用します。

df.drop('location', axis = 1, inplace = True)

もちろん、これら XNUMX つの列を同時に削除することもできます。

df = df.drop(['buyer', 'location'], axis=1)

どちらのアプローチでも、次のデータフレームが返されます。

 

Python でデータ クリーニングの技術を習得する

さまざまな理由でデータセット内に重複データが発生する可能性があり、分析が歪む可能性があります。

データセット内の重複を検出してみましょう。 その方法は次のとおりです。

以下のコードはメソッドを使用します Duplicate() データセット全体の重複を考慮します。 デフォルト設定では、値の最初の出現を一意とみなし、その後の出現を重複とみなされます。 この動作は、 続ける パラメータ。 たとえば、df.duplicated(keep=False) は、最初に出現したものを含むすべての重複を True としてマークします。

# Detecting duplicates
duplicates = df[df.duplicated()]
duplicates

これが出力です。

 

Python でデータ クリーニングの技術を習得する
 

同じ値を持つ行 3 が最初に出現するため、インデックス 2 を持つ行は重複としてマークされています。

次に、重複を削除する必要があります。これを次のコードで行います。

# Detecting duplicates
duplicates = df[df.duplicated()]
duplicates

  ドロップ_重複() 関数は重複を識別する際にすべての列を考慮します。 特定の列のみを考慮したい場合は、df.drop_duplicates(subset=['column1', 'column2']) のように、リストとしてこの関数に渡すことができます。

 

Python でデータ クリーニングの技術を習得する
 

ご覧のとおり、重複した行が削除されています。 ただし、インデックス付けは同じままで、インデックス 3 が欠落しています。 インデックスをリセットすることでこれを整理します。

df = df.reset_index(drop=True)

このタスクは、 リセットインデックス() 関数。 drop=True 引数は、元のインデックスを破棄するために使用されます。 この引数を含めない場合、古いインデックスが DataFrame の新しい列として追加されます。 Drop=True を設定すると、古いインデックスを忘れてデフォルトの整数インデックスにリセットするようにパンダに指示します。

練習のために、試してみてください この Microsoft データセットから重複を削除します.

場合によっては、データ型が正しく設定されていない可能性があります。 たとえば、日付列は文字列として解釈される可能性があります。 これらを適切な型に変換する必要があります。

データセットでは、オブジェクト データ型として表示されている列 Advertise_date と sale_date に対してこれを行います。 また、日付の形式は行ごとに異なります。 それを日付に変換するとともに、一貫性を持たせる必要があります。

最も簡単な方法は to_datetime() 方法。 ここでも、以下に示すように、列ごとに実行できます。

これを行う場合、一部の日付が日から始まるため、dayfirst 引数を True に設定します。

# Converting advertisement_date column to datetime
df['advertisement_date'] = pd.to_datetime(df['advertisement_date'], dayfirst = True) # Converting sale_date column to datetime
df['sale_date'] = pd.to_datetime(df['sale_date'], dayfirst = True)

を使用して両方の列を同時に変換することもできます。 apply() メソッド to_datetime().

# Converting advertisement_date and sale_date columns to datetime
df[['advertisement_date', 'sale_date']] = df[['advertisement_date', 'sale_date']].apply(pd.to_datetime, dayfirst = True)

どちらのアプローチでも同じ結果が得られます。

 

Python でデータ クリーニングの技術を習得する
 

これで、日付が一貫した形式になりました。 すべてのデータが変換されていないことがわかります。 Advertise_date には XNUMX つの NaT 値があり、sale_date には XNUMX つの NaT 値があります。 これは日付が欠落していることを意味します。

を使用して列が日付に変換されるかどうかを確認してみましょう。 info() 方法。

# Get a concise summary of the dataframe
print(df.info())

 

Python でデータ クリーニングの技術を習得する
 

ご覧のとおり、両方の列は datetime64[ns] 形式ではありません。

ここで、データを TEXT から NUMERIC に変換してみます。 Airbnb データセット.

現実世界のデータセットには欠損値が存在することがよくあります。 特定のアルゴリズムではそのような値を処理できないため、欠損データの処理は非常に重要です。

この例には欠損値もいくつか含まれているため、欠損データを処理するための最も一般的な XNUMX つのアプローチを見てみましょう。

欠損値のある行の削除

データが欠落している行の数が観測値の総数に比べて重要でない場合は、これらの行を削除することを検討してください。

この例では、最後の行には平方フィートと広告日以外の値がありません。 このようなデータは使用できないので、この行を削除しましょう。

行のインデックスを示すコードは次のとおりです。

df = df.drop(8)

DataFrame は次のようになります。

 

Python でデータ クリーニングの技術を習得する
 

最後の行が削除され、DataFrame の見た目が良くなりました。 ただし、まだ不足しているデータがいくつかありますので、別のアプローチを使用して処理します。

欠損値の代入

重大な欠損データがある場合は、削除よりも補完の方が良い戦略になる可能性があります。 このプロセスには、他のデータに基づいて欠損値を埋めることが含まれます。 数値データの場合、一般的な補完方法には、中心傾向の尺度 (平均、中央値、最頻値) の使用が含まれます。

すでに変更されたデータフレームでは、advertising_date 列と sale_date 列に NaT (Not a Time) 値があります。 これらの欠損値を次を使用して代入します。 平均() 方法。

このコードでは、 fillna() NULL 値を見つけて平均値で埋めるメソッド。

# Imputing values for numerical columns
df['advertisement_date'] = df['advertisement_date'].fillna(df['advertisement_date'].mean())
df['sale_date'] = df['sale_date'].fillna(df['sale_date'].mean())

XNUMX 行のコードで同じことを行うこともできます。 私たちが使用するのは、 apply() を使用して定義された関数を適用するには ラムダ。 上記と同様に、この関数は fillna() および 平均() 欠損値を埋めるメソッド。

# Imputing values for multiple numerical columns
df[['advertisement_date', 'sale_date']] = df[['advertisement_date', 'sale_date']].apply(lambda x: x.fillna(x.mean()))

どちらの場合も出力は次のようになります。

 

Python でデータ クリーニングの技術を習得する
 

sale_date 列には不要な時間が含まれています。 それらを削除しましょう。

私たちは strftime() メソッド。日付を文字列表現と特定の形式に変換します。

df['sale_date'] = df['sale_date'].dt.strftime('%Y-%m-%d')

 

Python でデータ クリーニングの技術を習得する
 

日付がすべて整然と表示されるようになりました。

使用する必要がある場合 strftime() 複数の列で、再び使用できます ラムダ 次の方法で。

df[['date1_formatted', 'date2_formatted']] = df[['date1', 'date2']].apply(lambda x: x.dt.strftime('%Y-%m-%d'))

ここで、欠落しているカテゴリ値を代入する方法を見てみましょう。

カテゴリ データは、類似した特性を持つ情報をグループ化するために使用されるデータのタイプです。 これらの各グループはカテゴリです。 カテゴリ データは数値 (「男性」を示す「1」、「女性」を示す「2」など) を取ることができますが、それらの数値は数学的な意味を持ちません。 たとえば、それらを一緒に追加することはできません。

カテゴリデータは通常、次の XNUMX つのカテゴリに分類されます。

  1. 公称データ: これは、カテゴリにラベルが付けられているだけで、特定の順序で並べることができない場合です。 例としては、性別 (男性、女性)、血液型 (A、B、AB、O)、色 (赤、緑、青) などが挙げられます。
  1. 順序データ: このとき、カテゴリを並べ替えたり、ランク付けしたりできます。 カテゴリ間の間隔は等間隔ではありませんが、カテゴリの順序には意味があります。 例には、評価スケール (映画の 1 ~ 5 の評価)、教育レベル (高校、学部、大学院)、またはがんの段階 (ステージ I、ステージ II、ステージ III) が含まれます。

欠落しているカテゴリデータを代入するには、通常、このモードが使用されます。 この例では、列 property_category はカテゴリカル (公称) データですが、XNUMX つの行にデータが欠落しています。

欠損値をモードに置き換えましょう。

# For categorical columns
df['property_category'] = df['property_category'].fillna(df['property_category'].mode()[0])

このコードでは、 fillna() property_category 列内のすべての NaN 値を置き換える関数。 それをモードに置き換えます。

さらに、[0] 部分は、このシリーズから最初の値を抽出するために使用されます。 複数のモードがある場合は、最初のモードが選択されます。 モードが XNUMX つしかない場合でも、正常に動作します。

これが出力です。

 

Python でデータ クリーニングの技術を習得する
 

データはかなり良くなりました。 残っている唯一のことは、外れ値があるかどうかを確認することです。

これで null の処理を​​練習できます メタインタビューの質問ここで、NULL をゼロに置き換える必要があります。

外れ値は、他の観測値とは明らかに異なる、データセット内のデータ ポイントです。 それらは、データセット内の他の値から非常に遠く離れて、全体的なパターンの外側に存在する場合があります。 これらの値は、残りのデータと比較して著しく高いか低いため、異常であると考えられます。

異常値は、次のようなさまざまな理由で発生する可能性があります。

  • 測定または入力エラー
  • データ破損
  • 真の統計的異常

外れ値は、データ分析と統計モデリングの結果に大きな影響を与える可能性があります。 これらは、偏った分布や偏りを引き起こしたり、基礎となる統計的仮定を無効にしたり、推定されたモデルの適合を歪めたり、予測モデルの予測精度を低下させたり、誤った結論を導き出したりする可能性があります。

外れ値を検出するために一般的に使用される方法には、Z スコア、IQR (四分位範囲)、箱ひげ図、散布図、データ視覚化手法などがあります。 一部の高度なケースでは、機械学習手法も使用されます。

データを視覚化すると、外れ値を特定するのに役立ちます。 Seaborn の箱ひげ図はこれに便利です。

plt.figure(figsize=(10, 6))
sns.boxplot(data=df[['advertised_price', 'sale_price']])

plt.figure() を使用して、Figure の幅と高さをインチ単位で設定します。

次に、advertised_price 列と sale_price 列の箱ひげ図を作成します。これは次のようになります。

 

Python でデータ クリーニングの技術を習得する
 

これを上記のコードに追加することで、プロットを改良して使いやすくすることができます。

plt.xlabel('Prices')
plt.ylabel('USD')
plt.ticklabel_format(style='plain', axis='y')
formatter = ticker.FuncFormatter(lambda x, p: format(x, ',.2f'))
plt.gca().yaxis.set_major_formatter(formatter)

上記のコードを使用して、両方の軸のラベルを設定します。 また、Y 軸の値は科学表記法で示されており、それを価格値に使用できないことにも気付きます。 そこで、 plt.ticklabel_format() 関数を使用して、これをプレーン スタイルに変更します。

次に、千の位の区切り文字としてカンマと小数点を使用して y 軸の値を表示するフォーマッタを作成します。 最後のコード行はこれを軸に適用します。

出力は次のようになります。

 

Python でデータ クリーニングの技術を習得する
 

では、外れ値を特定して削除するにはどうすればよいでしょうか?

その方法の XNUMX つは IQR メソッドを使用することです。

IQR (四分位範囲) は、データセットを四分位に分割することによって変動を測定するために使用される統計手法です。 四分位は、ランク順のデータ セットを 25 つの等しい部分に分割し、第 75 四分位 (XNUMX パーセンタイル) と第 XNUMX 四分位 (XNUMX パーセンタイル) の範囲内の値が四分位範囲を構成します。

四分位範囲は、データ内の外れ値を特定するために使用されます。 仕組みは次のとおりです。

  1. まず、第 1 四分位 (Q3)、第 3 四分位 (Q1) を計算し、IQR を決定します。 IQR は QXNUMX – QXNUMX として計算されます。
  2. Q1 – 1.5IQR を下回る値、または Q3 + 1.5IQR を超える値は外れ値とみなされます。

箱ひげ図では、箱は実際に IQR を表します。 ボックス内の線は中央値 (または第 1.5 四分位数) です。 箱ひげ図の「ひげ」は、Q1 と Q3 から XNUMX*IQR 以内の範囲を表します。

これらのひげの外側にあるデータ ポイントは外れ値と見なすことができます。 私たちの場合、それは 12,000,000 ドルの価値です。 箱ひげ図を見ると、これがいかに明確に表現されているかがわかります。これは、外れ値を検出する際にデータの視覚化がなぜ重要であるかを示しています。

次に、Python コードで IQR メソッドを使用して外れ値を削除しましょう。 まず、宣伝された価格の外れ値を削除します。

Q1 = df['advertised_price'].quantile(0.25)
Q3 = df['advertised_price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['advertised_price'] (Q1 - 1.5 * IQR)) |(df['advertised_price'] > (Q3 + 1.5 * IQR)))]

まず、次の式を使用して最初の四分位数 (または 25 番目の百分位数) を計算します。 分位数() 関数。 第 75 四分位数または XNUMX パーセンタイルについても同じことを行います。

これらは、それぞれデータの 25% と 75% が下回る値を示しています。

次に、四分位間の差を計算します。 ここまでの作業はすべて、IQR のステップを Python コードに変換しているだけです。

最後のステップとして、外れ値を削除します。 つまり、Q1 – 1.5 * IQR 未満、または Q3 + 1.5 * IQR を超えるすべてのデータです。

「~」演算子は条件を否定するため、外れ値ではないデータのみが残ります。

次に、販売価格でも同じことができます。

Q1 = df['sale_price'].quantile(0.25)
Q3 = df['sale_price'].quantile(0.75)
IQR = Q3 - Q1
df = df[~((df['sale_price'] (Q1 - 1.5 * IQR)) |(df['sale_price'] > (Q3 + 1.5 * IQR)))]

もちろん、 forループ.

for column in ['advertised_price', 'sale_price']: Q1 = df[column].quantile(0.25) Q3 = df[column].quantile(0.75) IQR = Q3 - Q1 df = df[~((df[column] (Q1 - 1.5 * IQR)) |(df[column] > (Q3 + 1.5 * IQR)))]

ループは XNUMX つの列を繰り返します。 列ごとに IQR を計算し、DataFrame 内の行を削除します。

この操作は、最初にadvertised_priceに対して、次にsale_priceに対してという順番で実行されることに注意してください。 その結果、DataFrame は各列のインプレースで変更され、いずれかの列で外れ値であるために行が削除される可能性があります。 したがって、この操作では、advertised_price と sale_price の外れ値を個別に削除し、後で結果を結合する場合よりも行数が少なくなる可能性があります。

この例では、どちらの場合でも出力は同じになります。 箱ひげ図がどのように変化したかを確認するには、前と同じコードを使用して箱ひげ図を再度プロットする必要があります。

plt.figure(figsize=(10, 6))
sns.boxplot(data=df[['advertised_price', 'sale_price']])
plt.xlabel('Prices')
plt.ylabel('USD')
plt.ticklabel_format(style='plain', axis='y')
formatter = ticker.FuncFormatter(lambda x, p: format(x, ',.2f'))
plt.gca().yaxis.set_major_formatter(formatter)

これが出力です。

 

Python でデータ クリーニングの技術を習得する
 

Python でパーセンタイルの計算を練習するには、 総会のインタビューの質問.

データ クリーニングは、データ分析プロセスにおける重要なステップです。 時間がかかる場合がありますが、結果の正確性を確保することが重要です。

幸いなことに、Python のライブラリの豊富なエコシステムにより、このプロセスはより管理しやすくなります。 不要な行と列を削除し、データを再フォーマットし、欠損値や外れ値に対処する方法を学びました。 これらは、ほとんどのデータに対して実行する必要がある通常の手順です。 ただし、場合によっては、 XNUMX つの列を XNUMX つに結合する, 既存のデータを検証する, それにラベルを割り当てるまたは 空白を取り除く.

これはすべてデータ クリーニングです。これにより、乱雑な現実世界のデータを、自信を持って分析できる適切に構造化されたデータセットに変えることができます。 最初に使用したデータセットと最終的に完成したデータセットを比較してください。

この結果に満足感が得られず、きれいなデータに妙に興奮しない人は、いったいデータ サイエンスで何をしているのでしょう!
 

ネイト・ロシディ データサイエンティストであり、製品戦略に携わっています。 彼はまた、分析を教える非常勤教授であり、 ストラタスクラッチ、データサイエンティストがトップ企業からの実際の面接の質問で面接の準備をするのを支援するプラットフォーム。 彼とつながる Twitter:StrataScratch or LinkedIn.

タイムスタンプ:

より多くの KDナゲット