탐색적 데이터 분석, Exploratory Data Analysis
from google.colab import drive
drive.mount('/content/drive')
pd.read_csv('filepath', sep=',')
pd.read_excel('filepath', sheet_name='Sheet1')
pd.read_json('filepath')
df.to_csv('filepath', sep=',', index=False)
df.to_excel('filepath', sheet_name='Output')
df.to_json('filepath', indent=2)
df.to_json(
path_or_buf: 'FilePath | WriteBuffer[bytes] | WriteBuffer[str] | None' = None,
orient: "Literal['split', 'records', 'index', 'table', 'columns', 'values'] | None" = None,
date_format: 'str | None' = None,
double_precision: 'int' = 10,
force_ascii: 'bool_t' = True,
date_unit: 'TimeUnit' = 'ms',
default_handler: 'Callable[[Any], JSONSerializable] | None' = None,
lines: 'bool_t' = False,
compression: 'CompressionOptions' = 'infer',
index: 'bool_t | None' = None,
indent: 'int | None' = None,
storage_options: 'StorageOptions | None' = None,
mode: "Literal['a', 'w']" = 'w',
) -> 'str | None'
sample_size = 1000
arr1 = 5 * np.random.randn(sample_size) + 53.9
arr2 = 4 * np.random.randn(sample_size) + 32.7
(arr - np.mean(arr)) / np.std(arr)
df["z-score"] = (df["column"] - df["column"].mean()) / df["column"].std()
df = pd.DataFrame({"data1": arr1, "data2": arr2})
mean1 = np.mean(df["data1"])
mean2 = np.mean(df["data2"])
std1 = np.std(df["data1"], ddof=1)
std2 = np.std(df["data2"], ddof=1)
df["data1_z_score"] = (df["data1"] - mean1) / std1
df["data2_z_score"] = (df["data2"] - mean2) / std2
df
df = pd.DataFrame({"data1": arr1, "data2": arr2})
mean1, mean2 = tuple(df.mean().to_list())
std1, std2 = tuple(df.std().to_list())
df["data1_z_score"] = (df["data1"] - mean1) / std1
df["data2_z_score"] = (df["data2"] - mean2) / std2
df
import scipy.stats as stats
df = pd.DataFrame({"data1": arr1, "data2": arr2})
df["data1_z_score"] = stats.zscore(df["data1"], ddof=1)
df["data2_z_score"] = stats.zscore(df["data2"], ddof=1)
df
from sklearn.preprocessing import StandardScaler
df = pd.DataFrame({"data1": arr1, "data2": arr2})
standard_scaler = StandardScaler()
df_z_score = pd.DataFrame(standard_scaler.fit_transform(df), columns=["data1_z_score", "data2_z_score"])
# 1. pd.concat([df1, df2])
df_result1 = pd.concat([df, df_z_score], axis=1)
# 2. df.join(df2, how="left")
df_result3 = df.join(df_z_score)
(arr - np.mean(arr)) / np.std(arr)
df["z-score"] = (df["column"] - df["column"].mean()) / df["column"].std()
df = pd.DataFrame({"data1": arr1, "data2": arr2})
max1 = np.max(df["data1"])
max2 = np.max(df["data2"])
min1 = np.min(df["data1"])
min2 = np.min(df["data2"])
df["data1_min_max_score"] = (df["data1"] - min1) / (max1 - min1)
df["data2_min_max_score"] = (df["data2"] - min2) / (max2 - min2)
df
df = pd.DataFrame({"data1": arr1, "data2": arr2})
max1, max2 = tuple(df.max().to_list())
min1, min2 = tuple(df.min().to_list())
df["data1_min_max_score"] = (df["data1"] - min1) / (max1 - min1)
df["data2_min_max_score"] = (df["data2"] - min2) / (max2 - min2)
df
from sklearn.preprocessing import MinMaxScaler
df = pd.DataFrame({"data1": arr1, "data2": arr2})
min_max_scaler = MinMaxScaler()
df_min_max_score = pd.DataFrame(min_max_scaler.fit_transform(df), columns=["data1_min_max_score", "data2_min_max_score"])
df.join(df_min_max_score)
왜도 (Skewness) | 제곱근 변환 | 로그 변환 | 역수 변환 |
---|---|---|---|
양수 | sqrt(x) | log(x) | |
log10(x) | 1 / x | ||
음수 | sqrt(max(x + 1) - x) | log(max(x + 1) - x) | |
log10(max(x + 1) - x) | 1 / (max(x + 1) - x) |
연속형 변수를 범주형 변수로 변환하는 작업이다.
def makeScore(x):
result = round(x)
if result > 100:
return 100
elif result < 50:
return 50
else:
return result
data = list(map(lambda x: makeScore(x), np.random.randn(1000) * 12 + 70))
df = pd.DataFrame(data, columns=["math_score"])
import matplotlib.pyplot as plt
plt.hist(df, bins=5, range=[50,100], rwidth=0.9)
plt.show()
loc
을 통해서 변경해야한다.df["grade"] = np.nan
df["grade"] = df["grade"].astype("str")
# df[df["math_score"] >= 90]["grade"] = "A" # SettingWithCopyWarning
df.loc[df["math_score"] >= 90, "grade"] = "A"
df.loc[(df["math_score"] >= 80) & (df["math_score"] < 90), "grade"] = "B"
df.loc[(df["math_score"] >= 70) & (df["math_score"] < 80), "grade"] = "C"
df.loc[(df["math_score"] >= 60) & (df["math_score"] < 70), "grade"] = "D"
df.loc[df["math_score"] < 60, "grade"] = "F"
df
df["grade2"] = pd.cut(df["math_score"], bins=[0, 60, 70, 80, 90, 101], labels= ["F", "D", "C", "B", "A"], right=False, include_lowest=True)
# cut 함수
pd.cut(
x,
bins,
right: 'bool' = True,
labels=None,
retbins: 'bool' = False,
precision: 'int' = 3,
include_lowest: 'bool' = False,
duplicates: 'str' = 'raise',
ordered: 'bool' = True,
)
bins
를 직접 수치로 지정하는 반면,q
)를 정해주면,df["grade3"] = pd.qcut(df["math_score"], q=5, labels=["F", "D", "C", "B", "A"])
# qcut 함수
pd.qcut(
x,
q,
labels=None,
retbins: 'bool' = False,
precision: 'int' = 3,
duplicates: 'str' = 'raise',
)
주성분 분석이란 여러 변수들의 변량을 주성분이라고 불리는, 서로 상관성이 높은 여러 변수들의 선형조합으로 만든 새로운 변수들로 요약, 축소하는 기법이다.
sklearn.decomposition.PCA
클래스 활용sklearn.decomposition.PCA(
n_components=None,
*,
copy=True,
whiten=False,
svd_solver='auto',
tol=0.0,
iterated_power='auto',
n_oversamples=10,
power_iteration_normalizer='auto',
random_state=None,
)
df = pd.read_csv("https://raw.githubusercontent.com/YoungjinBD/dataset/main/iris.csv")
df = df.drop(columns=["species"])
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
# 표준 정규화
standard_scaler = StandardScaler()
df = pd.DataFrame(standard_scaler.fit_transform(df), columns=df.columns)
# PCA 수행
pca = PCA(n_components=4)
p_score = pca.fit_transform(df)
print(pca.explained_variance_ratio_)
# 출력
# [0.72962445 0.22850762 0.03668922 0.00517871]
df[df['column'] == 1]
assert (df[np.isin(df.season, [1, 2])].index == df[(df.season == 1) | (df.season == 2)].index).all()
assert (df[np.isin(df.season, [1, 2])].index == df.iloc[np.isin(df.season, [1, 2])].index).all()
assert (df[np.isin(df.season, [1, 2])].index == df.loc[np.isin(df.season, [1, 2])].index).all()
assert (df[df.season.isin([1, 2])].index == df[np.isin(df.season, [1, 2])].index).all()
df.isin(values: 'Series | DataFrame | Sequence | Mapping') -> 'DataFrame'
np.isin(arr1, arr2)
np.in1d(arr1, arr2)
np.isin(
element,
test_elements,
assume_unique=False,
invert=False,
*,
kind=None,
) -> ndarray
df.quantile(.45, numeric_only=True)
df.quantile([.01, .99], numeric_only=True)
df.quantile(
q: 'float | AnyArrayLike | Sequence[float]' = 0.5,
axis: 'Axis' = 0,
numeric_only: 'bool' = False,
interpolation: 'QuantileInterpolation' = 'linear',
method: "Literal['single', 'table']" = 'single',
) -> 'Series | DataFrame'
percentile_1, percentile_99 = tuple(df['casual'].quantile([0.01, 0.99]).values)
cond_1 = df['casual'] >= percentile_1
cond_2 = df['casual'] <= percentile_99
df[cond_1 & cond_2]
df.isna().sum()
df.isnull()
== df.isna()
df.notnull()
== df.notna()
df.isna().any(axis=1).sum()
df[df.isna().any(axis=1)].index.tolist()
df['column'].fillna(value)
df['column'].fillna(method='ffill', limit=10)
df['column'].fillna(method='bfill')
df['column'].replace(oldValue, newValue)
df.fillna(
value: 'Hashable | Mapping | Series | DataFrame | None' = None,
*,
method: 'FillnaOptions | None' = None,
axis: 'Axis | None' = None,
inplace: 'bool_t' = False,
limit: 'int | None' = None,
downcast: 'dict | None | lib.NoDefault' = <no_default>,
) -> 'Self | None'
df.groupby("column1")["column2"].transform("mean")
df = pd.read_csv("https://raw.githubusercontent.com/YoungjinBD/dataset/main/titanic.csv")
df_groupby_age_mean = df.groupby(by="Pclass")["Age"].transform("mean")
df["Age"] = df["Age"].fillna(df_groupby_age_mean)
assert df["Age"].isna().sum() == 0
df.tail()
df.dropna()
df.dropna(how='any', axis=0)
df.dropna(how='all')
df.dropna(
*,
axis: 'Axis' = 0,
how: 'AnyAll | lib.NoDefault' = <no_default>,
thresh: 'int | lib.NoDefault' = <no_default>,
subset: 'IndexLabel | None' = None,
inplace: 'bool' = False,
ignore_index: 'bool' = False,
) -> 'DataFrame | None'
df.isin(['A', 'B'])
df['column'].isin([1, 2, 3])
df.isin(values: 'Series | DataFrame | Sequence | Mapping') -> 'DataFrame'
df_new.sort_values(by = ['Petal.Length', 'Petal.Width']).reset_index(drop=True)
df.sort_values('column')
df.sort_values(['column1', 'column2'], ascending=False)
df.sort_values(
by: 'IndexLabel',
*,
axis: 'Axis' = 0,
ascending: 'bool | list[bool] | tuple[bool, ...]' = True,
inplace: 'bool' = False,
kind: 'SortKind' = 'quicksort',
na_position: 'str' = 'last',
ignore_index: 'bool' = False,
key: 'ValueKeyFunc | None' = None,
) -> 'DataFrame | None'
df.reset_index(drop=True)
df.reset_index(
level: 'IndexLabel | None' = None,
*,
drop: 'bool' = False,
inplace: 'bool' = False,
col_level: 'Hashable' = 0,
col_fill: 'Hashable' = '',
allow_duplicates: 'bool | lib.NoDefault' = <no_default>,
names: 'Hashable | Sequence[Hashable] | None' = None,
) -> 'DataFrame | None'
df.sample(n = 10).reset_index(drop=False)
df.sample(frac=0.1, replace=True).reset_index()
df.sample(
n: 'int | None' = None,
frac: 'float | None' = None,
replace: 'bool_t' = False,
weights=None,
random_state: 'RandomState | None' = None,
axis: 'Axis | None' = None,
ignore_index: 'bool_t' = False,
) -> 'Self'
df.sample(n = 10).reset_index(drop=False)
df.sample(frac=0.1, replace=True).reset_index()
df[['column1', 'column2', 'column3']].set_index(['column1', 'column2'])
df.xs(key='index1_value')
df.xs(key=('index1_value', 'index2_value')
df.reset_index(
level: 'IndexLabel | None' = None,
*,
drop: 'bool' = False,
inplace: 'bool' = False,
col_level: 'Hashable' = 0,
col_fill: 'Hashable' = '',
allow_duplicates: 'bool | lib.NoDefault' = <no_default>,
names: 'Hashable | Sequence[Hashable] | None' = None,
) -> 'DataFrame | None'
df.set_index(
keys,
*,
drop: 'bool' = True,
append: 'bool' = False,
inplace: 'bool' = False,
verify_integrity: 'bool' = False,
) -> 'DataFrame | None'
# cross section
df2.xs(
key: 'IndexLabel',
axis: 'Axis' = 0,
level: 'IndexLabel | None' = None,
drop_level: 'bool_t' = True,
) -> 'Self'
df['season'].astype('str')
df['holiday'].astype('bool')
df.astype(
dtype,
copy: 'bool_t | None' = None,
errors: 'IgnoreRaise' = 'raise',
) -> 'Self'
sklearn.preprocessor.LabelEncoder
클래스 활용from sklearn.preprocessing import LabelEncoder
labelEncoder = LabelEncoder()
# fit, transform
labelEncoder.fit(sorted(np.unique(df["Sex"])))
df["Sex"] = labelEncoder.transform(df["Sex"])
# fit_transform
df["Embarked"] = labelEncoder.fit_transform(df["Embarked"])
OneHotEncoder(
*,
categories='auto',
drop=None,
sparse_output=True,
dtype=<class 'numpy.float64'>,
handle_unknown='error',
min_frequency=None,
max_categories=None,
feature_name_combiner='concat',
)
OneHotEncoder
는 scikit-learn
의 다른 도구들과 통합되어 머신러닝 파이프라인에 쉽게 포함될 수 있습니다.fit
과 transform
메서드를 사용해야 하므로, 사용법이 약간 더 복잡할 수 있습니다.import pandas as pd
from sklearn.preprocessing import OneHotEncoder
# 예제 데이터 생성
df = pd.DataFrame({
'color': ['red', 'blue', 'green', 'blue', 'red']
})
# OneHotEncoder 사용
encoder = OneHotEncoder(sparse_output=False)
encoded = encoder.fit_transform(df[['color']])
encoded_df = pd.DataFrame(encoded, columns=encoder.get_feature_names_out(['color']))
print(encoded_df)
sparse_output
옵션True
: 원-핫 인코딩 결과를 희소 행렬로 반환합니다. 메모리 효율성이 높습니다.False
: 원-핫 인코딩 결과를 밀집 행렬로 반환합니다. 메모리 사용량이 더 많지만, 일부 상황에서는 더 편리할 수 있습니다.sparse_output
옵션은 scikit-learn
의 OneHotEncoder
에서 희소 행렬(sparse matrix)과 밀집 행렬(dense matrix) 중 어떤 형태로 출력을 받을지를 결정하는 옵션입니다.
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
# 예제 데이터 생성
df = pd.DataFrame({
'color': ['red', 'blue', 'green', 'blue', 'red']
})
# OneHotEncoder 사용 (희소 행렬 출력)
encoder_sparse = OneHotEncoder(sparse_output=True)
encoded_sparse = encoder_sparse.fit_transform(df[['color']])
print("Sparse Matrix:\n", encoded_sparse)
# OneHotEncoder 사용 (밀집 행렬 출력)
encoder_dense = OneHotEncoder(sparse_output=False)
encoded_dense = encoder_dense.fit_transform(df[['color']])
encoded_df_dense = pd.DataFrame(encoded_dense, columns=encoder_dense.get_feature_names_out(['color']))
print("\nDense Matrix:\n", encoded_df_dense)
pd.get_dummies(
data,
prefix=None,
prefix_sep: 'str | Iterable[str] | dict[str, str]' = '_',
dummy_na: 'bool' = False,
columns=None,
sparse: 'bool' = False,
drop_first: 'bool' = False,
dtype: 'NpDtype | None' = None,
) -> 'DataFrame'
DataFrame
에 포함할 수 있으며, 원본 데이터와 쉽게 결합할 수 있습니다.OneHotEncoder
보다 제공되는 옵션이 적습니다.python코드 복사
import pandas as pd
# 예제 데이터 생성
df = pd.DataFrame({
'color': ['red', 'blue', 'green', 'blue', 'red']
})
# get_dummies 사용
encoded_df = pd.get_dummies(df, columns=['color'])
print(encoded_df)
특성 | OneHotEncoder (sklearn) | get_dummies (pandas) |
---|---|---|
통합된 머신러닝 파이프라인 | 예, scikit-learn 파이프라인 통합 | 아니요 |
사용법 | 상대적으로 복잡 (fit, transform) | 간단 (한 줄 코드) |
자동 처리 | 예, 새로운 데이터에 대해 자동 처리 | 아니요 |
제공 옵션 | 다양 (다양한 인코딩 옵션 제공) | 제한적 (기본 원-핫 인코딩 제공) |
결과 형태 | numpy 배열 (또는 DataFrame) | DataFrame |
mlxtend.preprocessing.TransactionEncoder
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
# 예제 거래 데이터
transactions = [
['milk', 'bread', 'eggs'],
['bread', 'butter'],
['milk', 'bread', 'butter'],
['bread', 'eggs']
]
# TransactionEncoder 인스턴스 생성
te = TransactionEncoder()
# 거래 데이터를 One-Hot 인코딩 형식으로 변환
te_ary = te.fit(transactions).transform(transactions)
# 변환된 데이터를 데이터프레임으로 변환
df = pd.DataFrame(te_ary, columns=te.columns_)
print(df)
# 출력 결과
bread butter eggs milk
0 True False True True
1 True True False False
2 True True False True
3 True False True False
평활화의 목적은 값의 변화를 매끄럽게 하여 데이터의 추세(경향)를 알기 쉽게 하는 것이다.
이전 n개의 데이터의 비가중 / 가중 평균
- 단순이동평균 (Simple Moving Average)
```
df.rolling(
window: 'int | dt.timedelta | str | BaseOffset | BaseIndexer',
min_periods: 'int | None' = None,
center: 'bool_t' = False,
win_type: 'str | None' = None,
on: 'str | None' = None,
axis: 'Axis | lib.NoDefault' = <no_default>,
closed: 'IntervalClosedType | None' = None,
step: 'int | None' = None,
method: 'str' = 'single',
) -> 'Window | Rolling'
```