CSV পড়া ও পরিষ্কার করা
এই পাঠে যা শিখবেন
- CSV কী — কেন AI-এর সব tabular ডেটা এতে
read_csv()-এর মূল params — sep, header, names, encoding- dtype manually দেওয়া — memory ও speed-এ লাভ
- parse_dates ও na_values — date ও missing automatic detect
- String column পরিষ্কার — strip, lower, regex
- Type conversion — pd.to_numeric, pd.to_datetime (errors='coerce')
- Duplicate ও save — drop_duplicates, to_csv, to_parquet
১ · CSV কী — কেন AI-তে এত গুরুত্বপূর্ণ
CSVCSV (Comma-Separated Values)একটি plain-text tabular format — প্রতিটি row একটি লাইন, column comma দিয়ে আলাদা। ১৯৭০-এর দশক থেকে চলমান। সব ভাষা, সব tool এতে read/write পারে — তাই universal data exchange-এ rajaa। হলো AI-র সবচেয়ে সাধারণ data format। Excel, Google Sheets, R, Python, SQL — সব tool এতে কাজ করে। সরকারি ডেটা (BBS, A2I), Kaggle dataset, IoT sensor log — অধিকাংশ CSV-তে।
কিন্তু বাস্তব CSV প্রায় কখনো "পরিষ্কার" নয় — column name-এ space, missing value নানা রূপে ("N/A", "NaN", "-"), date string-এ inconsistency, duplicate row, encoding mismatch। AI মডেল train-এর আগে — এই data cleaning-ই সময়ের ৬০-৮০% নেয়।
২ · read_csv basics — মূল params
ধরুন আমাদের একটি দোকানের sales ডেটা shop_sales.csv:
import pandas as pd
from io import StringIO
# Demo CSV — বাংলাদেশের দোকানের sales
csv_text = """date,product,price_bdt,qty,customer
2025-01-15,চাল ৫কেজি,450,2,রহিম উদ্দিন
2025-01-15,তেল ১লিটার,180,1,সালমা বেগম
2025-01-16,ডাল ১কেজি,140,3,করিম মিয়া
2025-01-16,চিনি ১কেজি,125,1,ফাতেমা খাতুন
"""
# Basic read
df = pd.read_csv(StringIO(csv_text))
print(df)
print()
print("Shape:", df.shape)
print("Columns:", list(df.columns))
১) sep=',' — separator (TSV হলে '\t')।
২) header=0 — কোন row header (None দিলে header নেই)।
৩) names=[...] — নিজে column name দিতে।
৪) index_col='id' — কোন column-কে index।
৫) encoding='utf-8' — বাংলা data-র জন্য আবশ্যক।
৬) nrows=1000 — preview-এ প্রথম N row।
encoding='utf-8' বা 'utf-8-sig' (BOM থাকলে) দিন। Windows Excel-এ save করলে কখনো 'cp1252' বা 'latin-1' লাগে। ভুল encoding দিলে বাংলা অক্ষর "??????" হয়ে যাবে।
৩ · dtype hint — কেন manually দিতে হয়
read_csv default-এ column-এর type inference করে — কিন্তু সবসময় সঠিক নয়। বড় ফাইলে এই inference slow এবং memory-হাঙ্গরী। dtypedtype (data type)একটি column-এর data type — int64, float64, object (string), datetime64 ইত্যাদি। সঠিক dtype = কম memory + দ্রুত operation। int8 (1 byte) vs int64 (8 byte) — ১০ GB → ১.৩ GB। manually দিলে — memory ৫-১০× কমে, read ২-৩× দ্রুত।
import pandas as pd
from io import StringIO
csv_text = """student_id,name,marks,grade
101,আরিফা সুলতানা,87,A
102,মুনির হাসান,72,B
103,তানিয়া আক্তার,95,A
104,সাদিকুর রহমান,68,B
"""
# dtype manually — অনেক দ্রুত ও memory-efficient
dtypes = {
"student_id": "int32", # 4 byte (default int64 = 8 byte)
"name": "string", # nullable string (default object)
"marks": "int8", # 0-127 যথেষ্ট
"grade": "category", # repeating values — category দ্রুত
}
df = pd.read_csv(StringIO(csv_text), dtype=dtypes)
print(df.dtypes)
print()
print(f"Memory: {df.memory_usage(deep=True).sum()} bytes")
category dtype — যখন একই value বহুবার আসে (যেমন "A", "B", "C" grade)। ১০ লক্ষ row-এর CSV-এ category column ১০-৫০× কম memory নেয়।
৪ · parse_dates ও na_values — automatic detection
Date-string default-এ object (string) থাকে — datetime অপারেশন (sort, diff, year extract) করা যায় না। parse_dates দিলে — auto-cast।
Missing value — CSV-তে নানা রূপে ("N/A", "NA", "NaN", "-", "null", খালি)। NaNNaN (Not a Number)Pandas-এ missing value-র representation — IEEE 754 floating-point standard থেকে। NaN-এ যেকোনো arithmetic NaN দেয়। isna()/notna() দিয়ে check; fillna()/dropna() দিয়ে handle। হিসেবে recognize করতে — na_values param।
import pandas as pd
from io import StringIO
# বাস্তব dirty CSV — date string ও nana রূপের missing value
csv_text = """order_date,customer,amount,status
2025-01-15,রহিম,450,paid
2025-01-16,সালমা,N/A,pending
2025-01-17,করিম,-,paid
2025-01-18,ফাতেমা,1250,
2025-01-19,তানিয়া,null,paid
"""
df = pd.read_csv(
StringIO(csv_text),
parse_dates=["order_date"], # date column auto-cast
na_values=["N/A", "-", "null", ""], # সব missing variant
)
print(df)
print()
print(df.dtypes)
print()
print("Missing per column:")
print(df.isna().sum())
order_date এখন datetime64[ns], amount NaN-সহ float। isna().sum() — প্রতি column-এ কতগুলো missing — exploration-এর প্রথম ধাপ।
৫ · Inspection ও column cleanup
CSV পড়ার পর প্রথম কাজ — কী আছে দেখা। df.info(), df.describe(), df.head(), df.sample(5)। তারপর column name পরিষ্কার (extra space, mixed case)।
import pandas as pd
from io import StringIO
# Column name-এ space, mixed case, inconsistent
csv_text = """ Order ID , Customer Name ,Total Amount ,Order Date
1, রহিম উদ্দিন ,450,2025-01-15
2,SALMA BEGUM,180,2025-01-16
3,karim mia,140,2025-01-17
"""
df = pd.read_csv(StringIO(csv_text))
print("Original columns:", list(df.columns))
# 1) column name পরিষ্কার — strip + lower + underscore
df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
print("Cleaned columns:", list(df.columns))
# 2) rename specific
df = df.rename(columns={"order_id": "id", "customer_name": "customer"})
print()
print(df.head())
print()
df.info()
৬ · String column পরিষ্কার
Customer name-এ leading/trailing space, mixed case — সব unify করতে .str accessor। Vectorized — for-loop-এর চেয়ে ১০০× দ্রুত।
import pandas as pd
df = pd.DataFrame({
"customer": [" রহিম উদ্দিন ", "SALMA BEGUM", "karim mia", "Fatema-Khatun"],
"phone": ["+880-1711-123456", "01712 345 678", "8801713-987654", "1714.222.333"],
})
# 1) Whitespace পরিষ্কার
df["customer"] = df["customer"].str.strip()
# 2) Lowercase + একাধিক space একটায়
df["customer_clean"] = (
df["customer"]
.str.lower()
.str.replace(r"\s+", " ", regex=True) # multiple space → 1
.str.replace("-", " ", regex=False)
)
# 3) Phone — সব non-digit বাদ
df["phone_clean"] = df["phone"].str.replace(r"\D", "", regex=True)
print(df)
str.replace(regex=True) — যেকোনো regex pattern। \s+ = এক বা একাধিক whitespace, \D = non-digit। AI text preprocessing-এর backbone।
৭ · Type conversion — to_numeric, to_datetime
Read-এর সময় miss করলেও — পরে cast করা যায়। errors='coerce' দিলে — invalid value NaN হয়ে যায় (crash না করে)।
import pandas as pd
df = pd.DataFrame({
"price": ["450", "180.5", "invalid", "1,250", ""],
"date": ["2025-01-15", "15/01/2025", "Jan 17, 2025", "bad", None],
})
# 1) Numeric conversion — comma সরাও আগে
df["price_num"] = (
df["price"]
.str.replace(",", "", regex=False)
.pipe(pd.to_numeric, errors="coerce") # invalid → NaN
)
# 2) Datetime conversion — multiple format try
df["date_parsed"] = pd.to_datetime(
df["date"],
errors="coerce",
format="mixed", # multi-format auto-infer
)
print(df)
print()
print(df.dtypes)
৮ · Duplicate handling
import pandas as pd
df = pd.DataFrame({
"order_id": [1, 2, 3, 2, 4, 4],
"customer": ["রহিম", "সালমা", "করিম", "সালমা", "ফাতেমা", "ফাতেমা"],
"amount": [450, 180, 140, 180, 1250, 1250],
})
print("Before:", len(df))
print("Duplicate rows:", df.duplicated().sum())
# সম্পূর্ণ identical row বাদ
df_dedup = df.drop_duplicates()
print("After full dedup:", len(df_dedup))
# নির্দিষ্ট column-এ — order_id-তে duplicate, প্রথমটা রাখো
df_unique = df.drop_duplicates(subset=["order_id"], keep="first")
print(df_unique)
৯ · Save — to_csv ও parquet preview
import pandas as pd
df = pd.DataFrame({
"id": [1, 2, 3],
"product": ["চাল", "তেল", "ডাল"],
"price": [450, 180, 140],
})
# CSV — index=False দরকার, encoding utf-8
df.to_csv("clean_sales.csv", index=False, encoding="utf-8")
print("Saved to CSV")
# Parquet — binary, columnar, ১০-৫০× ছোট
# df.to_parquet("clean_sales.parquet", engine="pyarrow")
# print("Saved to Parquet")
# Read back to verify
df_back = pd.read_csv("clean_sales.csv", encoding="utf-8")
print(df_back)
index=False — না দিলে output-এ extra "Unnamed: 0" column আসবে। ParquetParquetApache-এর columnar binary format। CSV-র চেয়ে ১০-৫০× ছোট, ৫-১০× দ্রুত read। Schema preserved (dtype বাঁচে)। Big data + AI pipeline-এ standard। PyArrow বা Fastparquet দিয়ে read/write। = production AI pipeline-এ standard। CSV human-readable, Parquet machine-efficient।
১০ · বাংলা CSV — common gotcha
- Encoding mismatch: Windows Excel save করলে CP-1252 বা UTF-8-with-BOM। Linux/Mac default UTF-8। বাংলা অক্ষর "????" হয়ে গেলে — encoding ভুল।
-
BOM (Byte Order Mark): File-এর শুরুতে invisible 3 byte (
)। প্রথম column name-এ যুক্ত হয়। Solution:encoding='utf-8-sig'। -
Comma in field: "ঢাকা, বাংলাদেশ" — comma আছে। Quote না দিলে column shift। Pandas auto-handle করে যদি
"..."দিয়ে wrapped থাকে। -
Mixed line endings: Windows
\r\n, Unix\n। Pandas auto-handle, কিন্তু custom parser-এ সমস্যা। -
Date format: বাংলাদেশে DD/MM/YYYY, US-এ MM/DD/YYYY।
dayfirst=Trueদিন।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ একটি বাংলা CSV file Excel-এ save করার পর Python-এ পড়লে অক্ষর "????" হয়ে যাচ্ছে। UTF-8, UTF-16, Windows-1252 — কোনটা কী? BOM কী? Detect ও fix-এর systematic উপায় কী?
বাংলা/Unicode data নিয়ে কাজ করার সময় encoding সবচেয়ে সাধারণ frustration। সঠিক বুঝলে — ১৫ মিনিটের সমস্যা সমাধান হয়, ভুল বুঝলে — ৫ ঘণ্টা গায়েব।
Encoding কী:
- প্রতিটি অক্ষর = একটি বা একাধিক byte। কোন byte কোন অক্ষর — সেটাই encoding।
- ASCII (1963) — শুধু English (1 byte/char, 128 char)।
- Unicode = সব ভাষার character set (১,১১,৪০০+ codepoint)।
- UTF-8/16/32 = Unicode encode করার বিভিন্ন scheme।
UTF-8 (universal default):
- Variable-length: ১-৪ byte per character।
- English (ASCII compat) ১ byte, বাংলা সাধারণত ৩ byte।
- Linux, Mac, Web, Python 3 — সবার default।
- "ক" = E0 A6 95 (3 byte)।
UTF-16:
- ২ বা ৪ byte/char। বাংলা ২ byte।
- Windows internal, Java internal।
- BOM (Byte Order Mark) প্রয়োজন — endianness বোঝাতে।
- Web-এ uncommon।
Windows-1252 (CP-1252):
- ASCII + ১২৮ extra char (European)।
- Windows পুরাতন default — Excel save legacy।
- বাংলা সমর্থন করে না — তাই বাংলা file CP-1252-এ save হলে data lost (replacement char দিয়ে)।
BOM (Byte Order Mark):
- File-এর শুরুতে invisible marker — encoding hint।
- UTF-8 BOM:
EF BB BF(ASCII-তে দেখায়)। - Excel সবসময় BOM যোগ করে — Pandas confused: প্রথম column name
"name"হয়ে যায়। - Solution:
encoding='utf-8-sig'— BOM auto-strip।
Detection workflow:
# 1) chardet/charset-normalizer দিয়ে detect
import chardet
with open("data.csv", "rb") as f:
raw = f.read(100000) # প্রথম 100KB যথেষ্ট
detected = chardet.detect(raw)
print(detected)
# {'encoding': 'utf-8', 'confidence': 0.99, ...}
# 2) Hex দেখা — প্রথম byte
# EF BB BF = UTF-8 BOM
# FF FE = UTF-16 LE
# FE FF = UTF-16 BE
# 3) Try-fail-fallback
encodings = ["utf-8-sig", "utf-8", "cp1252", "latin-1", "utf-16"]
for enc in encodings:
try:
df = pd.read_csv("data.csv", encoding=enc)
print(f"Worked: {enc}")
break
except UnicodeDecodeError:
continue
Fix strategies:
- Source-এ ঠিক করুন: Excel "Save As → CSV UTF-8" option ব্যবহার।
- Re-encode:
file.read().decode('cp1252').encode('utf-8')। - errors='replace': ভুল byte ? দিয়ে replace (data loss সম্ভব)।
- errors='ignore': ভুল byte skip (সাবধান)।
Real-world advice:
- সবসময় UTF-8 in your pipeline।
- Source data CP-1252 হলে — ingest pipeline-এ একবার convert।
- Excel থেকে এলে —
encoding='utf-8-sig'default। - Document encoding in README — team-এ confusion এড়াতে।
মূল উপলব্ধি: Encoding = byte-to-character mapping। Unicode/UTF-8 আজকের universal standard। বাংলা data-তে UTF-8 + BOM-aware ingest = ৯৯% সমস্যা solved। chardet + try-fallback = robust pipeline।
প্র ০২
read_csv default-এ অনেক column-কে object (string) dtype-এ রাখে। AI training-এর আগে কেন numeric/datetime cast দরকার? Memory ও speed-এর numbers কী?
dtype = data type। Pandas-এ এটাই ৭০% performance optimization। বুঝে dtype দিলে — ১০ GB CSV ১.৩ GB হয়, query ১০× দ্রুত।
Default behavior:
- read_csv first 1000 row sample করে dtype infer করে।
- String → object (Python list-of-strings, slow)।
- Numeric → int64 / float64 (8 byte each)।
- Date string → object — auto-parse করে না (parse_dates না দিলে)।
কেন cast আবশ্যক:
- Math operation: string-এ
+= concat, numeric-এ + = sum। - Comparison: "10" < "9" (string compare!) — wrong।
- Aggregation: mean/sum/median — numeric চাই।
- ML model: sklearn/TF/PyTorch — numpy float চায়।
- Date arithmetic: "যত দিন আগে" — datetime দরকার।
Memory comparison (১ million row):
default optimized saving
int64 → int8 8MB → 1MB 8×
float64 → float32 8MB → 4MB 2×
object → category 50MB → 2MB 25×
object → string[pyarrow] 50MB → 8MB 6×
Real benchmark:
- NYC Taxi 2GB CSV → optimized dtype → 350MB।
- Read time: 45s → 12s।
- groupby aggregation: 8s → 1s।
Cast strategies:
# Strategy 1 — read_csv-এ dtype dict
df = pd.read_csv("big.csv", dtype={
"user_id": "int32",
"rating": "float32",
"country": "category",
"name": "string"
})
# Strategy 2 — read পরে cast
df["price"] = pd.to_numeric(df["price"], errors="coerce")
df["date"] = pd.to_datetime(df["date"], errors="coerce")
df["cat"] = df["cat"].astype("category")
# Strategy 3 — downcast automatic
df["score"] = pd.to_numeric(df["score"], downcast="integer")
# auto picks smallest int that fits
Category dtype magic:
- Repeating string ("M"/"F", "A"/"B"/"C") → integer codes internally।
- ৫০ MB → ২ MB common।
- groupby/sort dramatically faster।
- ML-এ one-hot/label-encoding-এর pre-step।
Nullable types (modern):
- Int64 (capital I) — supports NaN unlike int64।
- string — better than object for text।
- Float32/Float64 — explicit nullable।
- boolean — supports NA।
Arrow backend (modern):
pd.read_csv("f.csv", dtype_backend="pyarrow")- Apache Arrow under the hood।
- Memory & speed dramatic improvement।
- String-heavy workload-এ ৫-১০× ভাল।
AI training impact:
- DataLoader speed = training speed bottleneck (often)।
- Wrong dtype → conversion per batch → GPU starvation।
- Tabular ML (XGBoost) — float32 preferred (GPU memory)।
- Embedding lookup — int32 index efficient।
Common mistakes:
- Phone number → int (leading 0 lost)। Use string।
- ID column → int64 default (waste)। Use int32 or string।
- Yes/No → object। Use category বা bool।
- Year → int64। Use int16 (1900-2100 fits in 16-bit)।
মূল উপলব্ধি: dtype = pandas optimization-এর foundation। Default safe কিন্তু wasteful। Production AI pipeline-এ — explicit dtype + category + parquet = ১০-১০০× efficiency। memory_usage(deep=True) দিয়ে measure করুন, then optimize।
প্র ০৩ Real-world dirty data — null variants ("N/A", "NaN", "-", ""), inconsistent spelling ("Dhaka"/"DHAKA"/"ঢাকা"), swapped columns। ছোট ১ MB CSV বনাম ১০ GB CSV — strategy আলাদা কেন?
Real CSV কখনই tutorial-এর মতো clean না। Strategy data scale-এর সাথে fundamentally পাল্টায় — ১ MB-তে যা trivial, ১০ GB-তে impossible।
Common dirtiness categories:
- Null variants: "", "N/A", "NaN", "null", "-", "?", "missing", "n/a", "NA"।
- Encoding noise: trailing space, BOM, hidden Unicode (zero-width)।
- Spelling variations: "Dhaka"/"dhaka"/"DHAKA"/"ঢাকা"/"Dhka" (typo)।
- Date chaos: "2025-01-15", "15/01/25", "Jan 15", "1/15/25"।
- Number chaos: "1,250", "1.250 BDT", "৳1250", "USD 12"।
- Schema drift: column add/remove between months।
- Swapped columns: source bug — name ও phone কখনো অদলবদল।
- Embedded delimiter: "Dhaka, Bangladesh" comma-cell।
- Multiline cell: address-এ newline।
Small CSV (<100 MB) strategy:
- Pandas in-memory load।
- Manual exploration:
head(),info(),value_counts()। - Eyeball every column — anomaly হাতে catch।
- Iterative fix — Jupyter cell-by-cell।
- Visual check: matplotlib histogram।
- Export cleaned version।
Large CSV (1-10 GB) strategy:
- Sample first:
nrows=10000দিয়ে structure বুঝুন। - Schema infer ও lock — explicit dtype।
- Chunked read:
chunksize=100000— process per chunk। - Dask/Polars consider: lazy evaluation, parallel।
- Convert to Parquet — future read ১০× faster।
- Sampling-based validation — 1% random sample-এ check।
Huge CSV (>10 GB) strategy:
- Pandas-এ আনার আগে — DuckDB/Polars/SQL।
- DuckDB:
SELECT * FROM 'data.csv' WHERE...— no load। - Spark for distributed cluster।
- Schema validation — Great Expectations, Pandera।
- Streaming pipeline — Apache Beam, Flink।
Null variant handling:
# All variants একসাথে
NA_VALS = ["", "N/A", "n/a", "NA", "NaN", "nan",
"null", "NULL", "-", "?", "missing", "."]
df = pd.read_csv("data.csv", na_values=NA_VALS, keep_default_na=True)
Spelling normalization:
# Step 1: lowercase + strip
df["city"] = df["city"].str.strip().str.lower()
# Step 2: known mapping
city_map = {
"dhaka": "Dhaka", "ঢাকা": "Dhaka",
"ctg": "Chittagong", "chittagong": "Chittagong",
"dhka": "Dhaka", # typo
}
df["city"] = df["city"].map(city_map).fillna(df["city"])
# Step 3: fuzzy match for residual
from rapidfuzz import process
unique = df["city"].unique()
for c in unique:
match, score, _ = process.extractOne(c, list(city_map.values()))
if score > 85:
df.loc[df["city"] == c, "city"] = match
Schema drift detection:
EXPECTED_COLS = {"id", "name", "amount", "date"}
cols = set(df.columns)
missing = EXPECTED_COLS - cols
extra = cols - EXPECTED_COLS
if missing:
raise ValueError(f"Missing: {missing}")
if extra:
print(f"Warning — new columns: {extra}")
Swapped columns detection:
- Statistical: phone column-এ all-digit expected; name-এ alphabet — heuristic check।
- Data dictionary cross-validate।
- Sample row eyeball দেখুন।
Modern alternative tools:
- Polars: Rust-backed, ৫-১০× pandas faster।
- DuckDB: SQL on CSV/Parquet without load।
- Dask: pandas API, parallel/distributed।
- Modin: drop-in pandas replacement।
Validation framework:
- Pandera: schema-as-code, fail-fast।
- Great Expectations: data quality test suite।
- cerberus: light-weight schema validator।
মূল উপলব্ধি: Small data — manual + iterative। Large data — schema-first, chunked, alternative engine। Validation = pipeline-এর প্রথম step। "Garbage in, garbage out" — AI-তে এই উক্তি বিশেষ true। ৬০% data scientist-এর সময় cleaning-এ। Tooling discipline = AI productivity।
প্র ০৪ CSV বনাম Parquet বনাম JSON — AI pipeline-এ কোনটা কখন? File size, read speed, schema preservation, tool compatibility — চারটি দৃষ্টিতে comparison।
File format choice = AI pipeline-এর hidden bottleneck। ভুল choice = ১০× slower training, ১০× higher cloud cost। Modern AI engineer তিনটিই জানে — কখন কোনটা।
CSV (Comma-Separated Values):
- Pros:
- Universal — every tool reads।
- Human-readable — text editor-এ open।
- Streaming-friendly — line-by-line।
- Excel/Google Sheets compatible।
- Cons:
- Largest size (no compression default)।
- Slowest read (parse + type infer)।
- No schema (every read re-infer)।
- No nested data।
- Encoding ambiguity।
- Use when: Data exchange, manual review, small data (<100 MB), human consumption।
Parquet (Apache, columnar):
- Pros:
- ৫-১০× smaller than CSV (Snappy/Gzip default)।
- ৫-১০× faster read (binary, columnar)।
- Schema preserved (dtype safe)।
- Column pruning — শুধু needed columns load।
- Predicate pushdown — filter at file level।
- Nested data support (struct, list, map)।
- Cons:
- Binary — text editor-এ খোলা যায় না।
- Excel direct support নেই।
- Append-friendly নয় (immutable)।
- PyArrow/Fastparquet dependency।
- Use when: Big data, AI training, data lake, repeated read, cloud storage (S3)।
JSON / JSONL:
- Pros:
- Nested data natural (dict, list)।
- Web API standard।
- Schema flexible — fields vary per row।
- Human-readable।
- JSONL (line-delimited) — streaming friendly।
- Cons:
- Verbose (key repeat per row)।
- Slower than Parquet, similar to CSV।
- Tabular data inefficient।
- Use when: API response, semi-structured (LLM outputs), nested record, log data, NoSQL export।
Benchmark — 10M row tabular dataset:
Format Size Write Read Compressed
─────────────────────────────────────────────────
CSV 850 MB 120 s 45 s No
CSV.gz 180 MB 140 s 55 s Yes
JSON 1.2 GB 150 s 65 s No
JSONL 1.1 GB 130 s 50 s No
Parquet 95 MB 18 s 8 s Snappy
Parquet+zstd 60 MB 25 s 9 s Zstd
Feather 105 MB 9 s 5 s LZ4
AI pipeline stages — কোনটা কখন:
- Ingest (raw): CSV/JSON থেকে আসে — clients এতে দেয়।
- Bronze layer (raw clean): Parquet — schema lock, compress।
- Silver layer (feature): Parquet — partitioned by date।
- Gold layer (model-ready): Parquet/Feather — fast load।
- Training: Parquet → DataLoader → batch।
- Export to client: CSV (universal)।
Modern alternatives:
- Feather (Arrow IPC): Fastest, no compression default. Memory-mapped। Short-term cache।
- HDF5: Scientific computing, large arrays. Hierarchical।
- Avro: Schema-evolution friendly, Kafka standard।
- ORC: Hadoop ecosystem, similar to Parquet।
- Delta Lake / Iceberg: Parquet + ACID transactions, version control।
Compression options:
- Snappy: fast compress/decompress, moderate ratio (Parquet default)।
- Gzip: better compression, slower।
- Zstd: best of both — recommended modern।
- LZ4: fastest, lower ratio।
- Brotli: best for text, slow।
Schema preservation matters:
# CSV — dtype lost
df.to_csv("f.csv")
df2 = pd.read_csv("f.csv") # all columns object/inferred again
# Parquet — dtype preserved
df.to_parquet("f.parquet")
df2 = pd.read_parquet("f.parquet") # exactly same dtypes
assert df.dtypes.equals(df2.dtypes)
Cloud cost reality:
- S3 storage: $0.023/GB/month — Parquet ১০× কম storage।
- S3 read: $0.0004/1000 GET — column pruning ১০× কম read।
- BigQuery/Athena query: byte-scanned billing — Parquet ১০-১০০× কম bill।
- 1 TB CSV → 100 GB Parquet → $২০/month → $২/month।
Decision flowchart:
- Human review করবে? → CSV।
- Nested data? → JSON।
- API response? → JSON।
- Big tabular + read repeated? → Parquet।
- Streaming append? → JSONL বা Avro।
- Need ACID? → Delta Lake।
- Quick interim cache? → Feather।
মূল উপলব্ধি: CSV = lingua franca (universal but inefficient)। Parquet = AI workhorse (binary, columnar, schema-safe)। JSON = nested/API data। ভাল engineer pipeline-এ multi-format flow design করেন — ingest CSV, store Parquet, export CSV। Format = silent performance lever। ১০× efficiency শুধু format change-এ পাওয়া যায়।
অনুশীলন
-
Read with options: নিচের CSV-text-কে read করুন — date parse, missing value detect, এবং price column-কে int8 dtype-এ।
order,date,price,status 1,2025-01-15,450,paid 2,2025-01-16,N/A,pending 3,2025-01-17,180,paidimport pandas as pd from io import StringIO csv_text = """order,date,price,status 1,2025-01-15,450,paid 2,2025-01-16,N/A,pending 3,2025-01-17,180,paid""" df = pd.read_csv( StringIO(csv_text), parse_dates=["date"], na_values=["N/A"], dtype={"order": "int16", "status": "category"}, ) # price-এ NaN আছে — int8-এ যায় না, Int16 nullable df["price"] = df["price"].astype("Int16") print(df.dtypes) print(df) -
String column পরিষ্কার: একটি name column যেখানে মিশ্রিত case + extra space আছে — সব title-case + single-space-এ আনুন।
import pandas as pd df = pd.DataFrame({ "name": [" রহিম উদ্দিন ", "SALMA BEGUM", "karim mia ", " Fatema "] }) df["name_clean"] = ( df["name"] .str.strip() .str.replace(r"\s+", " ", regex=True) .str.title() # English-এ প্রতি word capital ) print(df)বাংলা characters-এ
.title()no-op — শুধু English-এ কাজ করে। বাংলা data-তে strip+single-space যথেষ্ট। -
Type conversion safety: একটি price column-এ comma, BDT prefix, এবং invalid value — সব float-এ cast করুন (errors='coerce')।
import pandas as pd df = pd.DataFrame({ "price": ["450", "1,250 BDT", "৳180", "invalid", "৳1,500.50", None] }) df["price_num"] = ( df["price"] .astype(str) .str.replace(r"[^\d.]", "", regex=True) # শুধু digit ও . রাখো .replace("", None) .pipe(pd.to_numeric, errors="coerce") ) print(df) print(f"\nMissing: {df['price_num'].isna().sum()}")Regex
[^\d.]— digit ও dot বাদে সব বাদ। তারপর to_numeric — invalid → NaN।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ১৫ · groupby, merge ও pivot পরবর্তী পাঠ Clean data হাতে — এবার aggregation, join, reshape।
- পাঠ ১৩ · Pandas DataFrame পরিচিতি আগের পাঠ DataFrame কী, কীভাবে কাজ করে — ভিত্তি।
- পাঠ ০৮ · Error handling সম্পর্কিত CSV pipeline-এ try/except — robust ingest।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।