<jupyter_start><jupyter_text>Copyright (c) 2021 [윤기태]https://github.com/yoonkt200/learning-spoons-nano-degree[MIT License](https://github.com/yoonkt200/learning-spoons-nano-degree/blob/master/LICENSE.txt) LearningSpoons - NanoDegree-----  2회차 - (기초 EDA, 데이터 병합, 분석준비, 시각화 연습)- [1. 데이터의 기본 정보 파악하기](1.-데이터의-기본-정보-파악하기)    - [데이터의 크기, 데이터의 타입]    - [데이터의 열 정보 탐색]    - [데이터의 분포 탐색 : 결측치, 이상치에 대한 탐색]- [2. 데이터 관계 정리 및 전처리](2.-데이터-관계-정리-및-전처리)    - [데이터 병합]    - [결측 데이터 처리하기]- [3. 데이터 시각화 연습](3.-데이터-시각화-연습)    - [scatter plot]    - [box plot]    - [hist plot]    - [heatmap plot]    ----<jupyter_code>!pip install matplotlib
# -*- coding: utf-8 -*-

%matplotlib inline

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data_dir = "../dataset/"<jupyter_output><empty_output><jupyter_text>1. 데이터의 기본 정보 파악하기  [데이터의 크기 및 기본 정보] ---- *DataFrame, Series 살펴보기*<jupyter_code>olist_customers_dataset = pd.read_csv(data_dir + "olist_customers_dataset.csv")
olist_customers_dataset.head()
olist_customers_dataset.shape
olist_customers_dataset.info()
type(olist_customers_dataset)
customer_series = olist_customers_dataset['customer_id']
customer_series
type(customer_series)
customer_series.index
customer_series.values<jupyter_output><empty_output><jupyter_text>---- *여러 데이터셋 하나로 정리하기*<jupyter_code>empty_df = pd.DataFrame(columns=['a', 'b', 'c', 'd'])
empty_df = empty_df.append({'a': 1, 'b': 9, 'c': 9, 'd': 2}, ignore_index=True)
empty_df = empty_df.append({'a': 0, 'b': 6, 'c': 1, 'd': 3}, ignore_index=True)
empty_df.head()
empty_df.shape[1]
info_df = pd.DataFrame(columns=['row_num', 'col_num', 'name', 'pk'])

def info_df_row(name, pk, file_name):
    temp_df = pd.read_csv(data_dir + file_name)
    return {'row_num': temp_df.shape[0], 'col_num': temp_df.shape[1], 'name': name, 'pk': pk}
info_df = info_df.append(info_df_row("customer_data", "customer_id", "olist_customers_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("location_data", "geolocation_zip_code_prefix", "olist_geolocation_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("order_data", "order_id", "olist_order_items_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("payment_data", "order_id", "olist_order_payments_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("review_data", "review_id", "olist_order_reviews_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("shipping_data", "order_id", "olist_orders_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("product_data", "product_id", "olist_products_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("seller_data", "seller_id", "olist_sellers_dataset.csv"), ignore_index=True)
info_df = info_df.append(info_df_row("category_data", "product_category_name", "product_category_name_translation.csv"), ignore_index=True)
info_df<jupyter_output><empty_output><jupyter_text>---- [데이터의 열 정보 탐색] ---- *Categorical 열 정보 살펴보기*<jupyter_code>olist_customers_dataset.info()
olist_customers_dataset.columns
olist_customers_dataset.describe()
# transform to categorical feature
olist_customers_dataset = pd.DataFrame(olist_customers_dataset).astype('category')
olist_customers_dataset.info()
# Using from_records
data = [{'col_1': 3, 'col_2': 'a'},
        {'col_1': 2, 'col_2': 'b'},
        {'col_1': 1, 'col_2': 'c'},
        {'col_1': 0, 'col_2': 'd'}]
pd.DataFrame.from_records(data).head()
# nunique : number of unique category
olist_customers_dataset['customer_id'].nunique()
# make df : column name and category number
unique_counts = pd.DataFrame.from_records([(col, olist_customers_dataset[col].nunique()) for col in olist_customers_dataset.columns],
                          columns=['col_name', 'num_category'])
unique_counts<jupyter_output><empty_output><jupyter_text>---- *object(str)으로 다시 변경*<jupyter_code># transform to categorical feature
olist_customers_dataset = pd.DataFrame(olist_customers_dataset).astype('str')
olist_customers_dataset.info()
olist_customers_dataset.head()<jupyter_output><empty_output><jupyter_text>---- [데이터의 분포 탐색 : 결측치, 이상치에 대한 탐색] ---- *결측치 탐색*<jupyter_code>olist_products_dataset = pd.read_csv(data_dir + "olist_products_dataset.csv")
olist_products_dataset.head()
olist_products_dataset.shape
olist_products_dataset.info()
# 열 단위 탐색
olist_products_dataset['product_category_name'].isnull()
# 열 단위 탐색
olist_products_dataset['product_category_name'].isnull().sum()
# 전체 단위 탐색
olist_products_dataset.isnull()
# 전체 단위 탐색
olist_products_dataset.isnull().sum()<jupyter_output><empty_output><jupyter_text>---- *결측치 처리 - dropna()*<jupyter_code>olist_products_dataset['product_category_name'].nunique()
olist_products_dataset['product_category_name'].value_counts()
olist_products_dataset['product_category_name'].value_counts()[-10:]
olist_products_dataset = olist_products_dataset.dropna()
olist_products_dataset['product_category_name'].nunique()
olist_products_dataset['product_category_name'].value_counts()
olist_products_dataset['product_category_name'].value_counts()[-10:]<jupyter_output><empty_output><jupyter_text>---- *결측치 처리 - fillna()*<jupyter_code>olist_products_dataset = olist_products_dataset.fillna("some_value")<jupyter_output><empty_output><jupyter_text>---- *이상치 탐색 및 처리*<jupyter_code>olist_products_dataset.info()
olist_products_dataset['product_name_lenght'].hist(bins=50)
olist_products_dataset.boxplot(column=['product_name_lenght'])
olist_products_dataset[olist_products_dataset['product_name_lenght'] < 20].shape
olist_products_dataset['product_name_lenght'] = np.log(olist_products_dataset['product_name_lenght'])
olist_products_dataset['product_name_lenght'].hist(bins=50)
olist_products_dataset.boxplot(column=['product_name_lenght'])
olist_products_dataset[olist_products_dataset['product_name_lenght'] < 3.3].shape<jupyter_output><empty_output><jupyter_text>---- *numerical 열 전체 탐색*<jupyter_code>olist_products_dataset = pd.read_csv(data_dir + "olist_products_dataset.csv")
olist_products_dataset = olist_products_dataset.dropna()
numerical_columns = ['product_name_lenght', 'product_description_lenght', 'product_photos_qty', 'product_weight_g', 'product_length_cm', 'product_height_cm', 'product_width_cm']
olist_products_dataset.boxplot(column=[numerical_columns[0]])
olist_products_dataset.boxplot(column=[numerical_columns[1]])
olist_products_dataset.boxplot(column=[numerical_columns[2]])
olist_products_dataset.boxplot(column=[numerical_columns[3]])
olist_products_dataset.boxplot(column=[numerical_columns[4]])
olist_products_dataset.boxplot(column=[numerical_columns[5]])
olist_products_dataset.boxplot(column=[numerical_columns[6]])<jupyter_output><empty_output><jupyter_text>----  2. 데이터 관계 정리 및 전처리 ---- [데이터 병합]  *병합 대상 데이터 체크* - 주문 데이터셋 뼈대 : olist_order_items_dataset- 뼈대를 기본으로 부가 정보 병합 1. 시간대별 주문 데이터 분석    - 시간대별 주문 분석 -> ***주문시간 정보 병합 필요***    - 시간대별 주문 지역 분석 -> ***주문자 정보, 주문자의 거주 정보 병합 필요***2. 주문 상품의 카테고리 분석    - 주문 데이터에서 상품의 카테고리 비율 분석하기 -> ***상품의 카테고리 정보 병합 필요***    - 시간대별 주문 상품 카테고리 분석 (ex. 밤에 많이 사는 상품군) -> ***주문시간 정보 + 상품의 카테고리 정보 병합 필요***    - 일자/요일별 주문 상품 카테고리 분석 (ex. 일요일에 많이 사는 상품군) -> ***주문시간 정보 + 상품의 카테고리 정보 병합 필요***3. 배송 데이터 분석    - 평균 배송 시간 분석 -> ***배송 정보 병합 필요***    - 지역에 따른 배송 시간 분석 -> ***주문자 정보, 주문자의 거주 정보, 배송 정보 병합 필요***    - 예상 배송일과 실제 배송일간의 차이 분석 -> ***배송 정보 병합 필요***    - 상품 카테고리별 평균 배송 시간 분석 -> ***상품의 카테고리 정보, 배송 정보 병합 필요***<jupyter_code>order_df.columns
order_df = pd.read_csv(data_dir + "olist_order_items_dataset.csv")  # 뼈대 데이터
order_df.head()
shipping_df = pd.read_csv(data_dir + "olist_orders_dataset.csv")  # 주문시간 및 배송 관련 정보
shipping_df.head()
category_df = pd.read_csv(data_dir + "olist_products_dataset.csv")  # 상품 카테고리 정보
category_df.head()
user_df = pd.read_csv(data_dir + "olist_customers_dataset.csv")  # 주문자 정보, 주문자의 거주 정보
user_df.head()<jupyter_output><empty_output><jupyter_text>---- 참고 : *LEFT JOIN 형태로 DataFrame 병합*<jupyter_code>df1 = pd.DataFrame({'a': ['foo', 'bar'], 'b': [1, 2]})
df2 = pd.DataFrame({'a': ['foo', 'baz'], 'c': [3, 4]})
df1
df2
df1 = df1.merge(df2, how='left', on='a')
df1.head()<jupyter_output><empty_output><jupyter_text>---- *주문데이터 기준으로 데이터 병합*<jupyter_code>order_df['order_id'] = order_df['order_id'].astype(str)
shipping_df['order_id'] = shipping_df['order_id'].astype(str)
order_df = order_df.merge(shipping_df, how='left', on='order_id')
order_df.head()
order_df['product_id'] = order_df['product_id'].astype(str)
category_df['product_id'] = category_df['product_id'].astype(str)
order_df = order_df.merge(category_df, how='left', on='product_id')
order_df.head()
order_df['customer_id'] = order_df['customer_id'].astype(str)
user_df['customer_id'] = user_df['customer_id'].astype(str)
order_df = order_df.merge(user_df, how='left', on='customer_id')
order_df.head()<jupyter_output><empty_output><jupyter_text>---- *필요한 Columns 정리*  1. 시간대별 주문 데이터 분석    - 시간대별 주문 분석 -> `order_purchase_timestamp`    - 시간대별 주문 지역 분석 -> `order_purchase_timestamp, customer_city`2. 주문 상품의 카테고리 분석    - 주문 데이터에서 상품의 카테고리 비율 분석하기 -> `product_category_name`    - 시간대별 주문 상품 카테고리 분석 (ex. 밤에 많이 사는 상품군) -> `order_purchase_timestamp, product_category_name`    - 일자/요일별 주문 상품 카테고리 분석 (ex. 일요일에 많이 사는 상품군) -> `order_purchase_timestamp, product_category_name`3. 배송 데이터 분석    - 평균 배송 시간 분석 -> `order_purchase_timestamp, order_delivered_customer_date`    - 지역에 따른 배송 시간 분석 -> `customer_city, order_purchase_timestamp, order_delivered_customer_date`    - 예상 배송일과 실제 배송일간의 차이 분석 -> `order_estimated_delivery_date, order_delivered_customer_date`    - 상품 카테고리별 평균 배송 시간 분석 -> `order_purchase_timestamp, order_delivered_customer_date, product_category_name`<jupyter_code>order_df.columns
anal_columns = ['order_id', 'product_id', 'customer_id',  # 기본 id 정보들
                'order_purchase_timestamp', 'customer_city', 'product_category_name', 
                'order_delivered_customer_date', 'order_estimated_delivery_date',
                'order_status',  # 필터링에 사용되는 정보
                'price']  # 시각화용 정보
order_df = order_df[anal_columns]
order_df.head()<jupyter_output><empty_output><jupyter_text>---- [결측 데이터 처리하기]<jupyter_code>order_df.shape
order_df.isnull().sum()
order_df['product_category_name'].value_counts()
order_df = order_df.dropna()
order_df.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
Int64Index: 108659 entries, 0 to 112649
Data columns (total 10 columns):
 #   Column                         Non-Null Count   Dtype  
---  ------                         --------------   -----  
 0   order_id                       108659 non-null  object 
 1   product_id                     108659 non-null  object 
 2   customer_id                    108659 non-null  object 
 3   order_purchase_timestamp       108659 non-null  object 
 4   customer_city                  108659 non-null  object 
 5   product_category_name          108659 non-null  object 
 6   order_delivered_customer_date  108659 non-null  object 
 7   order_estimated_delivery_date  108659 non-null  object 
 8   order_status                   108659 non-null  object 
 9   price                          108659 non-null  float64
dtypes: float64(1), object(9)
memory usage: 9.1+ MB<jupyter_text>----  3. 데이터 시각화 연습 ---- [scatter plot]<jupyter_code>olist_products_dataset.columns
plt.scatter(olist_products_dataset['product_length_cm'], olist_products_dataset['product_width_cm'])
!pip install seaborn
import seaborn as sns
scatter_df = olist_products_dataset[['product_weight_g', 'product_length_cm', 'product_height_cm','product_width_cm']]
g = sns.PairGrid(scatter_df)
g.map(sns.scatterplot)<jupyter_output><empty_output><jupyter_text>---- [box plot]<jupyter_code>order_df.head()
sns.boxplot(y=order_df['product_category_name'], x=order_df['price'])
plt.show()
order_df['product_category_name'].value_counts()[:10]
top10_category = order_df['product_category_name'].value_counts()[:10].index.tolist()
top10_category_order_df = order_df[order_df['product_category_name'].isin(top10_category)]
sns.boxplot(y=top10_category_order_df['product_category_name'], x=top10_category_order_df['price'] );
plt.show()
product_category_name_translation = pd.read_csv(data_dir + "product_category_name_translation.csv")
product_category_name_translation.head()
top10_category_order_df = top10_category_order_df.merge(product_category_name_translation, how='left', on='product_category_name')
sns.boxplot(y=top10_category_order_df['product_category_name_english'], x=top10_category_order_df['price'] );
plt.show()<jupyter_output><empty_output><jupyter_text>---- [hist plot]<jupyter_code>order_df['price'].describe()
order_df['price'].hist(bins=100)
np.log(order_df['price']).hist(bins=100)
olist_products_dataset[['product_weight_g', 'product_length_cm', 'product_height_cm','product_width_cm']].hist(bins=30)<jupyter_output><empty_output><jupyter_text>---- [heatmap plot]<jupyter_code>import seaborn as sns

# 피처간의 상관계수 행렬
corr = olist_products_dataset[['product_weight_g', 'product_length_cm', 'product_height_cm','product_width_cm']].corr(method='pearson')
show_cols = ['product_weight_g', 'product_length_cm', 'product_height_cm','product_width_cm']

# corr 행렬 히트맵을 시각화
plt.rcParams['figure.figsize'] = [10, 8]
plt.rc('font', family='AppleGothic')
sns.set(font_scale=1.5)
hm = sns.heatmap(corr.values,
            cbar=True,
            annot=True, 
            square=True,
            fmt='.2f',
            annot_kws={'size': 10},
            yticklabels=show_cols,
            xticklabels=show_cols)

plt.tight_layout()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1420349738065373, 'fraction_numerical': 0.015789862023168302, 'mean_word_length': 5.777, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 95, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '19', 'dir': 'jupyter-structured-clean-dedup', 'id': '626100', 'license': 'MIT', 'n_tokens_mistral': 5958, 'n_tokens_neox': 6570, 'n_words': 861, 'path': '02/02_EDA.ipynb', 'repo_name': 'yoonkt200/learning-spoons-nano-degree', 'size': '13553'}