Python で汚れた CSV ファイルをクリーニングする方法:初心者向けガイド
KDnuggets が公開した本記事は、Python を用いて不揃いな CSV データを効率的にクリーニングする具体的な手順とコード例を初心者向けに解説している。
キーポイント
データクリーニングの基礎手法
欠損値の処理や型変換など、CSV データ整理に必要な基本的な Pandas メソッドを紹介しています。
実用的なコード例の提示
実際の不揃いデータに対して適用できる具体的な Python コードスニペットを提供し、即座に試せる構成となっています。
初心者向けの段階的アプローチ
複雑な処理を小さなステップに分けて解説することで、プログラミング初心者がデータ前処理の概念を理解しやすくしています。
影響分析・編集コメントを表示
影響分析
この記事は、AI やデータサイエンスの現場で頻繁に発生する「データの質」の問題に対する実用的な解決策を提示しており、特に初学者にとってデータ分析への第一歩をスムーズにする重要な役割を果たします。技術的な革新性という点では限定的ですが、現場での即戦力となるスキル向上に寄与するため、教育・学習コンテンツとしての価値は高いです。
編集コメント
本記事は特定の AI モデルや最新トレンドに関するものではなく、データ分析の基礎となる前処理技術に焦点を当てた実務ガイドです。
image**
# イントロダクション
データ分析を始めたばかりの頃、最初に学ぶことのひとつがデータのクリーニングです。一見基本的な作業に思えますが、これは何度も繰り返し使用する最も重要なスキルの一つです。
面白いことに、プロフェッショナルとして働いていても、データを分析したりモデルを構築したり結果を評価したりする時間よりも、むしろデータクリーニングに多くの時間を費やすことになります。なぜでしょうか?それは、生データ(raw data)はほとんどがきれいな状態ではないからです。欠損値、誤ったフォーマット、重複行、文字列の乱れ、無効な日付、奇妙なカテゴリ、ノイズの多いエントリなどが含まれている可能性があります。
データが何を語っているかを理解する前に、これらの問題を解決する必要があります。
本ガイドでは、Python と pandas** を使用して、 messy な顧客 CSV ファイルをクリーニングしていきます。まずはデータの読み込みと確認から始め、次に列名の整理、欠損値の処理、重複行の削除、テキストの標準化、データ型の変換、メールアドレスの有効性検証を行い、最後にクリーンな CSV ファイルとして保存します。
# 1. CSV の読み込み
最初のステップは、messy なデータセットを pandas に読み込むことです。
import pandas as pd
df = pd.read_csv("messy_customers.csv", keep_default_na=False)
df
顧客の CSV ファイルを使用しており、そこには一般的なデータ品質の問題が含まれています。すでにお分かりいただけるように、このファイルには見にくい列名、一貫性のないテキストフォーマット、混在する日付形式、欠損値、重複行、そして数値が文字列として保存されている項目が含まれています。
# 2. クリーニング前の調査
クリーニングを開始する前に、データセット内に実際に何が含まれているかを理解する必要があります。
print("Shape:", df.shape)
print("\nColumn names:")
print(df.columns.tolist())
print("\nData types:")
print(df.dtypes)
print("\nExact duplicate rows:", df.duplicated().sum())
出力結果:
Shape: (10, 8)
Column names:
[' Customer ID ', ' Full Name ', 'AGE', ' Email Address ', 'Join Date', 'City', 'Membership', 'Total Spend']
Data types:
Customer ID object
Full Name object
AGE object
Email Address object
Join Date object
City object
Membership object
Total Spend object
dtype: object
Exact duplicate rows: 1
これにより、変更を加える前にデータセットの概要をすばやく把握できます。
データセットには 10 行と 8 列があることがわかります。列名は見にくい状態です。一部の列名に余分なスペースが含まれており、大文字・小文字の使用が不統一だからです。また、すべての列がオブジェクト型として保存されていることも確認できます。これは通常、pandas がそれらをテキストとして扱っていることを意味します。
重複チェックの結果、完全一致する行が 1 行あることも示されています。これは、重複レコードが最終的な分析に影響を与える可能性があるため、早期に把握しておくのに役立ちます。
# 3. 列名のクリーニング
これで列名がごちゃごちゃしていることがわかったので、まずはそれらを整理しましょう。
df.columns = (
df.columns
.str.strip()
.str.lower()
.str.replace(r"\s+", "_", regex=True)
)
df.columns.tolist()
出力:
['customer_id',
'full_name',
'age',
'email_address',
'join_date',
'city',
'membership',
'total_spend']
このステップでは、列名から余分なスペースを削除し、すべてを小文字に変換して、スペースをアンダースコア(_)に置き換えます。
これで列名は扱いやすくなりました。"Email Address" のようにスペースを含む名前を書く代わりに、"email_address" とシンプルに記述できます。これによりコードがすっきりし、後々の小さなミスを防ぐのに役立ちます。
# 4. 空白文字とプレースホルダーの置換
次に、空白値や一般的なプレースホルダーを適切な欠損値(missing values)に置き換えましょう。
df = df.replace(r"^\s*$", pd.NA, regex=True)
df = df.replace(
["N/A", "n/a", "NA", "unknown", "not a date"],
pd.NA,
)
df.isna().sum()
出力:
customer_id 1
full_name 1
age 1
email_address 0
join_date 1
city 2
membership 1
total_spend 1
dtype: int64
実世界の CSV ファイルでは、欠損データはさまざまな形で表示されることがよくあります。一部のセルが空白になっている場合もあれば、"N/A" を使用している場合や、"unknown" や "not a date" のような値が使われている場合もあります。
これらすべてを適切な欠損値に変換することで、pandas が正しく検出できるようになります。このステップの後で、欠損値の集計、埋め込み、または削除がより容易になります。
# 5. 重複行の削除
次に、データセットから完全重複する行を削除します。
print("Rows before:", len(df))
df = df.drop_duplicates().copy()
print("Rows after:", len(df))
出力結果:
Rows before: 10
Rows after: 9
重複行は分析に問題を引き起こす可能性があります。同じレコードが複数回カウントされてしまうためです。
ここでは、重複削除前に 10 行ありましたが、削除後は 9 行になりました。これはデータセットから完全な重複行が 1 行削除されたことを意味します。
# 6. テキスト列のクリーニング
次に、テキストベースの列をクリーニングして値の一貫性を高めます。
text_columns = ["customer_id", "full_name", "email_address", "city", "membership"]
for column in text_columns:
df[column] = df[column].astype("string").str.strip()
df["full_name"] = (
df["full_name"]
.str.replace(r"\s+", " ", regex=True)
.str.title()
)
df["city"] = df["city"].str.title()
df["membership"] = df["membership"].str.lower()
df["email_address"] = df["email_address"].str.lower()
df[text_columns]

テキスト列は、同じ種類の情報を人によって異なる方法で記述するため、通常追加のクリーニングが必要です。
このステップでは、customer_id、full_name、email_address、city、membership から余分なスペースを削除します。その後、フォーマットを整えて、名前と都市にはタイトルケース(単語の頭文字を大文字)を適用し、メールアドレスとメンバーシップ値には小文字を使用するようにクリーニングを行います。
これによりデータセットが読みやすくなり、後でカテゴリに関する問題が発生するのを防ぐことができます。例えば、「Gold」、「GOLD」、「gold」はすべて同じメンバーシップ値として扱われるべきです。
# 7. カテゴリの標準化
次に、メンバーシップ列をクリーニングして、有効なカテゴリのみが含まれるようにします。
allowed_memberships = {"bronze", "silver", "gold"}
df.loc[~df["membership"].isin(allowed_memberships), "membership"] = pd.NA
df["membership"].value_counts(dropna=False)
出力:
membership
gold 4
silver 2
2
bronze 1
Name: count, dtype: Int64
このステップにより、メンバーシップ列に期待する値のみが含まれることが保証されます。
このデータセットでは、有効なメンバーシップタイプはブロンズ(bronze)、シルバー(silver)、ゴールド(gold)です。これらのカテゴリ外の値(例えばプラチナなど)は、後で処理できるように欠損値に置き換えられます。
# 8. 年齢の数値への変換
次に、年齢列をテキストから数値に変換します。
df["age"] = pd.to_numeric(df["age"], errors="coerce")
df.loc[~df["age"].between(0, 120), "age"] = pd.NA
df["age"] = df["age"].astype("Int64")
df[["full_name", "age"]]

年齢列はテキストとして保存されていたため、分析に使用する前に数値列に変換する必要があります。
また、負の年齢や 120 歳を超える年齢など、意味をなさない値も削除します。無効な年齢は欠損値に変換され、後で修正されます。
# 9. 混合された日付形式の変換
次に、join_date カラムをクリーニングします。
df["join_date"] = pd.to_datetime(
df["join_date"],
format="mixed",
dayfirst=True,
errors="coerce",
)
df[["full_name", "join_date"]]

日付は CSV ファイル内でしばしば不揃いになります。それは、異なる形式で表示される可能性があるためです。
このステップでは、join_date カラムを適切な日付時刻(datetime)カラムに変換します。ファイル内の日付がすべて同じ形式に従っているわけではないため、「mixed」を使用しています。無効な日付はすべて欠損値に変換されます。
# 10. 通貨値のクリーニング
次に、total_spend カラムをクリーニングします。
df["total_spend"] = (
df["total_spend"]
.astype("string")
.str.replace(r"[^0-9.-]", "", regex=True)
)
df["total_spend"] = pd.to_numeric(df["total_spend"], errors="coerce")
df[["full_name", "total_spend"]]

total_spend カラムには通貨記号、カンマ、およびテキスト値が含まれているため、pandas ではまだ数値として扱うことができません。
このステップでは、数字、小数点、マイナス記号以外のすべての文字を削除します。その後、カラムを数値型に変換して、合計や平均、その他の有用な指標の計算が可能になります。
# 11. メールアドレスの有効性の検証
次に、メールアドレスが有効な形式を持っているかを確認します。
email_pattern = r"^[^\s@]+@[^\s@]+\.[^\s@]+$"
valid_email = df["email_address"].str.match(email_pattern, na=False)
df.loc[~valid_email, "email_address"] = pd.NA
df[["full_name", "email_address"]]
これは単純な電子メールの検証ステップです。

各電子メールがメールアドレスの基本構造を持っているかを確認します。明らかに無効な電子メールの場合は、欠損値に置き換えます。これにより、email_address 列をよりクリーンで信頼性の高いものに保つことができます。
# 12. 欠損値の処理
次に、残りの欠損値に対してどうするかを決定します。
df = df.dropna(subset=["customer_id"]).copy()
df["full_name"] = df["full_name"].fillna("Unknown")
df["city"] = df["city"].fillna("Unknown")
df["membership"] = df["membership"].fillna("unassigned")
median_age = int(df["age"].median())
df["age"] = df["age"].fillna(median_age)
df["total_spend"] = df["total_spend"].fillna(0.0)
print("Median age used:", median_age)
df.isna().sum()
出力:
Median age used: 31
customer_id 0
full_name 0
age 0
email_address 1
join_date 1
city 0
membership 0
total_spend 0
dtype: int64
このデータセットでは、customer_id が欠落している行を削除します。なぜなら、customer_id は各顧客の主要な識別子だからです。
その他の列については、適切な代替値を使用します。名前と都市が欠落している場合は「Unknown」に、メンバーシップ値が欠落している場合は「unassigned」に、年齢が欠落している場合は中央値で埋め、支出額が欠落している場合は 0.0 で埋めます。
email_address と join_date にはまだ欠損値が残っていますが、それは問題ありません。時には、正しくない可能性のある値を無理やり設定するよりも、欠損値を残しておく方が望ましい場合もあります。
# 13. クリーン化されたデータの検証
最終ファイルを保存する前に、クリーン化されたデータセットが期待されるルールに従っているかを確認する必要があります。
final_memberships = {"bronze", "silver", "gold", "unassigned"}
assert df["customer_id"].notna().all()
assert df["customer_id"].is_unique
assert df["age"].between(0, 120).all()
assert df["total_spend"].ge(0).all()
assert df["membership"].isin(final_memberships).all()
print("All validation checks passed.")
出力:
All validation checks passed.
これらのチェックにより、重要なクリーニング手順が機能したことを確認できます。
各顧客に ID が存在すること、顧客 ID が一意であること、年齢が有効な範囲内にあること、総支出額が負の値ではないこと、メンバーシップ値が最終的に承認されたリストからのみのものであることを検証しています。すべてのチェックが通過すれば、このクリーン化されたデータセットをより自信を持って使用できるようになります。
# 14. 最終結果の確認
これでクリーン化されたデータセットを確認し、すべてが正しく表示されているか確認できます。
df.head()
この段階では、データは以前よりもはるかにクリーンになっています。
列名は整合性があり、テキスト値はクリーニング済みで、年齢列は数値形式になり、参加日は適切な日付形式となり、総支出列も計算の準備ができています。
この最終確認は、クリーニング済みのファイルを保存する前に、明らかな問題を素早く見つけるための最後の機会となるため重要です。
# 15. クリーニング済み CSV の保存
最後に、クリーニング済みのデータセットを新しい CSV ファイルとして保存します。
df.to_csv(
"clean_customers.csv",
index=False,
date_format="%Y-%m-%d",
)
print("Saved clean file to clean_customers.csv")
出力:
Saved clean file to clean_customers.csv
クリーニング済みのデータセットを別ファイルとして保存するのは、元の messy CSV ファイルが変更されないようにするためです。
これは良いプラクティスです。何か問題が発生した場合や、後で異なるクリーニングアプローチを適用したい場合に、いつでも生データファイルに戻ることができるからです。
# 最終的な考察
多くの人はデータセットのクリーニング方法を理解していると思っていますが、実際の課題はデータを分析用に本当に準備できたかどうかを確認し始める時点から始まります。
欠損値の削除や列名の修正だけでなく、データ型の確認、無効な値への対応、重複の除去、カテゴリの標準化、重要なフィールドの検証、そしてデータセットを信頼する前の最終チェックも必要です。
多くの初心者がここで失敗します。表面だけのデータクリーニングを行い、最終的なデータセットが意味をなすかどうかを検証していないのです。
このガイドでは、Python と pandas を使って messy な CSV ファイルをクリーニングするための、シンプルかつ実践的なワークフローを紹介しました。データの読み込み、検査、列のクリーニング、欠損値の処理、テキストの修正、数値と日付の変換、メールアドレスの検証、最終結果の確認、そしてクリーンな CSV ファイルへの保存までを行いました。
これは、ほぼあらゆる実世界のデータプロジェクトで再利用できるようなワークフローです。データセットは変わっても、プロセスは基本的に同じです:検査し、クリーニングし、検証し、保存する。
Abid Ali Awan ** (@1abidaliawan) は機械学習モデルの構築を愛する認定データサイエンティストです。現在、コンテンツ作成に注力し、機械学習やデータサイエンス技術に関する技術ブログの執筆を行っています。Abid はテクノロジー管理の修士号と電信工学の学士号を取得しています。彼のビジョンは、精神疾患で苦しむ学生のためにグラフニューラルネットワークを用いた AI 製品を構築することです。
原文を表示

**
# Introduction
When you are just starting out with data analysis, one of the first things you learn is how to clean a dataset. It sounds basic, but it is one of the most important skills you will use again and again.
The funny part is that even as a professional, you will still spend a lot of your time cleaning data instead of analyzing it, building models, or evaluating results. Why? Because raw data is rarely clean. It can have missing values, wrong formats, duplicate rows, messy strings, invalid dates, strange categories, and noisy entries.
Before you can understand what the data is telling you, you need to fix these issues.
In this guide, we will clean a messy customer CSV file using Python and pandas**. We will start by loading and inspecting the data, then clean column names, handle missing values, remove duplicates, standardize text, convert data types, validate emails, and save the final clean CSV file.
# 1. Loading the CSV
**
The first step is to load the messy dataset into pandas.
import pandas as pd
df = pd.read_csv("messy_customers.csv", keep_default_na=False)
df
We are using a customer CSV file that has common data quality issues. As you can already see, the file includes messy column names, inconsistent text formatting, mixed date formats, missing values, duplicate rows, and numbers stored as text.
# 2. Inspecting Before Cleaning
Before we start cleaning, we need to understand what is actually inside the dataset.
print("Shape:", df.shape)
print("\nColumn names:")
print(df.columns.tolist())
print("\nData types:")
print(df.dtypes)
print("\nExact duplicate rows:", df.duplicated().sum())Output:
Shape: (10, 8)
Column names:
[' Customer ID ', ' Full Name ', 'AGE', ' Email Address ', 'Join Date', 'City', 'Membership', 'Total Spend']
Data types:
Customer ID object
Full Name object
AGE object
Email Address object
Join Date object
City object
Membership object
Total Spend object
dtype: object
Exact duplicate rows: 1This gives us a quick overview of the dataset before making any changes.
We can see that the dataset has 10 rows and 8 columns. The column names are messy because some of them have extra spaces and inconsistent casing. We can also see that every column is stored as an object, which usually means pandas is treating them as text.
The duplicate check also shows that there is 1 exact duplicate row. This is useful to know early because duplicate records can affect the final analysis.
# 3. Cleaning the Column Names
Now that we know the column names are messy, we will clean them first.
df.columns = (
df.columns
.str.strip()
.str.lower()
.str.replace(r"\s+", "_", regex=True)
)
df.columns.tolist()Output:
['customer_id',
'full_name',
'age',
'email_address',
'join_date',
'city',
'membership',
'total_spend']This step removes extra spaces from the column names, converts everything to lowercase, and replaces spaces with underscores.
Now the column names are much easier to work with. Instead of writing names with spaces like Email Address, we can simply use email_address. This makes the code cleaner and helps avoid small mistakes later.
# 4. Replacing Blank Strings and Placeholders
Next, we will replace blank values and common placeholders with proper missing values.
df = df.replace(r"^\s*$", pd.NA, regex=True)
df = df.replace(
["N/A", "n/a", "NA", "unknown", "not a date"],
pd.NA,
)
df.isna().sum()Output:
customer_id 1
full_name 1
age 1
email_address 0
join_date 1
city 2
membership 1
total_spend 1
dtype: int64Real-world CSV files often show missing data in different ways. Some cells are blank, some use N/A, and some use values like unknown or not a date.
We convert all of these into proper missing values so pandas can detect them correctly. After this step, it becomes easier to count, fill, or remove missing values later.
# 5. Removing Duplicate Rows
Now we will remove exact duplicate rows from the dataset.
print("Rows before:", len(df))
df = df.drop_duplicates().copy()
print("Rows after:", len(df))Output:
Rows before: 10
Rows after: 9Duplicate rows can create problems in your analysis because the same record may be counted more than once.
Here, we had 10 rows before removing duplicates and 9 rows after. This means one exact duplicate row was removed from the dataset.
# 6. Cleaning Text Columns
Now we will clean the text-based columns so the values are more consistent.
text_columns = ["customer_id", "full_name", "email_address", "city", "membership"]
for column in text_columns:
df[column] = df[column].astype("string").str.strip()
df["full_name"] = (
df["full_name"]
.str.replace(r"\s+", " ", regex=True)
.str.title()
)
df["city"] = df["city"].str.title()
df["membership"] = df["membership"].str.lower()
df["email_address"] = df["email_address"].str.lower()
df[text_columns]
Text columns usually need extra cleaning because people write the same type of information in different ways.
In this step, we remove extra spaces from customer_id, full_name, email_address, city, and membership. Then we clean the formatting so names and cities use title case, while emails and membership values use lowercase.
This makes the dataset easier to read and also helps us avoid category issues later. For example, Gold, GOLD, and gold should all be treated as the same membership value.
# 7. Standardizing Categories
Now we will clean the membership column so it only contains valid categories.
allowed_memberships = {"bronze", "silver", "gold"}
df.loc[~df["membership"].isin(allowed_memberships), "membership"] = pd.NA
df["membership"].value_counts(dropna=False)Output:
membership
gold 4
silver 2
2
bronze 1
Name: count, dtype: Int64This step makes sure that the membership column only contains the values we expect.
In this dataset, the valid membership types are bronze, silver, and gold. Any value outside these categories, such as platinum, is replaced with a missing value so we can handle it later.
# 8. Converting Age to a Number
Next, we will convert the age column from text to numbers.
df["age"] = pd.to_numeric(df["age"], errors="coerce")
df.loc[~df["age"].between(0, 120), "age"] = pd.NA
df["age"] = df["age"].astype("Int64")
df[["full_name", "age"]]
The age column was stored as text, so we need to convert it into a numeric column before using it for analysis.
We also remove values that do not make sense, such as negative ages or ages above 120. Any invalid age is turned into a missing value, which we will fix later.
# 9. Converting Mixed Date Formats
Now we will clean the join_date column.
df["join_date"] = pd.to_datetime(
df["join_date"],
format="mixed",
dayfirst=True,
errors="coerce",
)
df[["full_name", "join_date"]]
Dates are often messy in CSV files because they can appear in different formats.
This step converts the join_date column into a proper datetime column. We use "mixed" because the dates in this file do not all follow the same format. Any invalid date is converted into a missing value.
# 10. Cleaning Currency Values
Next, we will clean the total_spend column.
df["total_spend"] = (
df["total_spend"]
.astype("string")
.str.replace(r"[^0-9.-]", "", regex=True)
)
df["total_spend"] = pd.to_numeric(df["total_spend"], errors="coerce")
df[["full_name", "total_spend"]]
The total_spend column contains currency symbols, commas, and text values, so pandas cannot treat it as a number yet.
This step removes everything except numbers, decimal points, and minus signs. Then we convert the column into a numeric value so we can calculate totals, averages, and other useful metrics.
# 11. Validating Email Addresses
Now we will check whether the email addresses have a valid format.
email_pattern = r"^[^\s@]+@[^\s@]+\.[^\s@]+$"
valid_email = df["email_address"].str.match(email_pattern, na=False)
df.loc[~valid_email, "email_address"] = pd.NA
df[["full_name", "email_address"]]This is a simple email validation step.

It checks whether each email has the basic structure of an email address. If an email is clearly invalid, we replace it with a missing value. This helps keep the email_address column cleaner and more reliable.
# 12. Handling Missing Values
Now we will decide what to do with the remaining missing values.
df = df.dropna(subset=["customer_id"]).copy()
df["full_name"] = df["full_name"].fillna("Unknown")
df["city"] = df["city"].fillna("Unknown")
df["membership"] = df["membership"].fillna("unassigned")
median_age = int(df["age"].median())
df["age"] = df["age"].fillna(median_age)
df["total_spend"] = df["total_spend"].fillna(0.0)
print("Median age used:", median_age)
df.isna().sum()Output:
Median age used: 31
customer_id 0
full_name 0
age 0
email_address 1
join_date 1
city 0
membership 0
total_spend 0
dtype: int64For this dataset, we remove rows where customer_id is missing because it is the main identifier for each customer.
For the other columns, we use sensible replacements. Missing names and cities become Unknown, missing membership values become unassigned, missing ages are filled with the median age, and missing spending values are filled with 0.0.
We still have missing values in email_address and join_date, and that is okay. Sometimes it is better to keep missing values instead of forcing a value that may not be correct.
# 13. Checking the Cleaned Data
Before saving the final file, we should check that the cleaned dataset follows the rules we expect.
final_memberships = {"bronze", "silver", "gold", "unassigned"}
assert df["customer_id"].notna().all()
assert df["customer_id"].is_unique
assert df["age"].between(0, 120).all()
assert df["total_spend"].ge(0).all()
assert df["membership"].isin(final_memberships).all()
print("All validation checks passed.")Output:
All validation checks passed.These checks help us confirm that the important cleaning steps worked.
We are checking that every customer has an ID, customer IDs are unique, ages are valid, total spend is not negative, and membership values are only from the final approved list. If all checks pass, we can feel more confident using this cleaned dataset.
# 14. Reviewing the Final Result
Now we can review the cleaned dataset and make sure everything looks correct.
df.head()At this stage, the data is much cleaner than before.

The column names are consistent, the text values have been cleaned, the age column is now numeric, the join date is in a proper date format, and the total spend column is ready for calculations.
This final review is important because it gives us one last chance to quickly spot any obvious issue before saving the cleaned file.
# 15. Saving the Clean CSV
Finally, we will save the cleaned dataset as a new CSV file.
df.to_csv(
"clean_customers.csv",
index=False,
date_format="%Y-%m-%d",
)
print("Saved clean file to clean_customers.csv")Output:
Saved clean file to clean_customers.csvWe save the cleaned dataset as a separate file so the original messy CSV stays unchanged.
This is a good practice because you can always go back to the raw file if something goes wrong or if you want to apply a different cleaning approach later.
# Final Thoughts
Most people think they know how to clean a dataset, but the real challenge starts when you have to make sure the data is actually ready for analysis.
It is not just about removing missing values or fixing column names. You also need to check data types, handle invalid values, remove duplicates, standardize categories, validate important fields, and run final checks before trusting the dataset.
That is where many beginners make mistakes. They clean the data on the surface, but they do not validate whether the final dataset makes sense.
In this guide, we followed a simple but practical workflow for cleaning a messy CSV file with Python and pandas. We loaded the data, inspected it, cleaned the columns, handled missing values, fixed text, converted numbers and dates, validated emails, checked the final result, and saved a clean CSV file.
This is the kind of workflow you can reuse in almost any real-world data project. The dataset may change, but the process stays mostly the same: inspect, clean, validate, and save.
Abid Ali Awan** (@1abidaliawan) is a certified data scientist professional who loves building machine learning models. Currently, he is focusing on content creation and writing technical blogs on machine learning and data science technologies. Abid holds a Master's degree in technology management and a bachelor's degree in telecommunication engineering. His vision is to build an AI product using a graph neural network for students struggling with mental illness.
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み