Sebagai praktisi data, kita semua tahu ritual pertama saat berhadapan dengan dataset baru: Exploratory Data Analysis (EDA). Kita menjalankan df.info()
, df.describe()
, df.isnull().sum()
, dan serangkaian perintah lainnya untuk “merasakan” data. Proses ini, meskipun penting, sering kali terasa repetitif dan memakan waktu.
Bagaimana jika kita bisa mengotomatiskan semua langkah awal tersebut dengan satu fungsi?
Hari ini, saya ingin membagikan sebuah fungsi Python. Fungsi ini dirancang untuk memberikan gambaran umum yang mendalam tentang DataFrame pandas Anda.
Solusi: Satu Fungsi untuk Menguasai Semuanya
Fungsi ini melakukan iterasi pada setiap kolom dalam DataFrame Anda dan secara cerdas mengekstrak metrik-metrik paling penting berdasarkan tipe datanya. Lupakan lagi mengetik perintah yang sama berulang kali!
Berikut adalah kode lengkapnya:
import pandas as pd
import numpy as np
def create_ultimate_data_profile(df):
if not isinstance(df, pd.DataFrame):
raise TypeError("Input must be a pandas DataFrame.")
records = []
for col in df.columns:
# Basic metrics
dtype = str(df[col].dtype)
missing_count = df[col].isnull().sum()
unique_count = df[col].nunique()
memory_usage = df[col].memory_usage(deep=True) / 1024 # in KB
# Initialize default metrics
distribution, skew_val, kurt_val = '-', '-', '-'
outlier_iqr, outlier_zscore = 0, 0
zero_count, negative_count = 0, 0
whitespace_count = 0
cardinality_level, top_value, top_freq_percent = '-', '-', '-'
time_range = '-'
# Metrics for numeric columns
if pd.api.types.is_numeric_dtype(df[col]) and df[col].nunique() > 1:
mean, std = df[col].mean(), df[col].std()
skew_val, kurt_val = df[col].skew(), df[col].kurt()
if -1 < skew_val < 1 and -3 < kurt_val < 3:
distribution = "✅ Normal"
else:
distribution = "⚠️ Not Normal"
Q1, Q3 = df[col].quantile(0.25), df[col].quantile(0.75)
IQR = Q3 - Q1
lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
outlier_iqr = ((df[col] < lower) | (df[col] > upper)).sum()
z_scores = np.abs((df[col] - mean) / std) if std > 0 else 0
outlier_zscore = (z_scores > 3).sum()
zero_count = (df[col] == 0).sum()
negative_count = (df[col] < 0).sum()
# Metrics for object/categorical columns
elif pd.api.types.is_object_dtype(df[col]):
if unique_count <= 10: cardinality_level = "Low"
elif 10 < unique_count <= 50: cardinality_level = "Medium"
else: cardinality_level = "High"
if not df[col].empty and missing_count != len(df):
counts = df[col].value_counts()
top_value = counts.index[0]
top_freq_percent = (counts.iloc[0] / len(df[col].dropna())) * 100
try:
whitespace_count = (df[col].str.strip() != df[col]).sum()
except AttributeError:
whitespace_count = 0
# Metrics for datetime columns
elif pd.api.types.is_datetime64_any_dtype(df[col]):
if not df[col].isnull().all():
min_date = df[col].min().strftime('%Y-%m-%d')
max_date = df[col].max().strftime('%Y-%m-%d')
time_range = f"{min_date} to {max_date}"
else:
time_range = "All values are null"
records.append({
'Data Type': dtype,
'Memory (KB)': memory_usage,
'Missing Count': missing_count,
'Unique Count': unique_count,
'Cardinality': cardinality_level,
'Distribution': distribution,
'Skewness': skew_val,
'Kurtosis': kurt_val,
'Outliers (IQR)': outlier_iqr,
'Outliers (Z-Score)': outlier_zscore,
'Zero Count': zero_count,
'Negative Count': negative_count,
'Whitespace Count': whitespace_count,
'Top Value': top_value,
'Top Value %': top_freq_percent,
'Time Range': time_range,
})
summary_df = pd.DataFrame(records, index=df.columns)
pd.options.display.float_format = '{:,.2f}'.format
return summary_df
dengan memanggilnya seperti ini, Anda dapat menginvestigasi data tersebut.
profiling_data = create_ultimate_data_profile(df)
profiling_data

Penutup
Dengan mengotomatiskan langkah-langkah EDA awal, Anda tidak hanya menghemat waktu tetapi juga memastikan konsistensi dalam analisis Anda. Silakan modifikasi dan sesuaikan fungsi ini sesuai dengan kebutuhan spesifik proyek Anda.