데이터셋: https://www.kaggle.com/datasets/olistbr/brazilian-ecommerce
CSV 파일을 불러와서 실제 데이터 분석하기
다음과 같은 Pandas 문법을 사용하면 csv 파일을 불러와서 DataFrame으로 변환할 수 있다.
Pandas DataFrame 문법을 사용하면 더 다양하고 자세한 데이터 분석이 가능해진다.
import pandas as pd
products = pd.read_csv("olist_products_dataset.csv", encoding='utf-8-sig')
customers = pd.read_csv("olist_customers_dataset.csv", encoding='utf-8-sig')
geolocation = pd.read_csv("olist_geolocation_dataset.csv", encoding='utf-8-sig')
order_items = pd.read_csv("olist_order_items_dataset.csv", encoding='utf-8-sig')
payments = pd.read_csv("olist_order_payments_dataset.csv", encoding='utf-8-sig')
reviews = pd.read_csv("olist_order_reviews_dataset.csv", encoding='utf-8-sig')
orders = pd.read_csv("olist_orders_dataset.csv", encoding='utf-8-sig')
sellers = pd.read_csv("olist_sellers_dataset.csv", encoding='utf-8-sig')
category_name = pd.read_csv("product_category_name_translation.csv", encoding='utf-8-sig')
테이블 살펴보고 각 컬럼이 의미하는 것을 파악하기
products
proudcts 테이블에는 product_id, product_category_name, product_name_length, product_description_length, products_photos_qty, product_weight_g, product_length_cm, product_height_cm, product_width_cm 컬럼이 존재한다.
products.info()
를 확인해보니 product_id에는 null값이 없지만 다른 컬럼에는 null값이 있다.- 컬럼명을 해석해보면 product_id: 상품 아이디, product_category_name: 상품 카테고리명, product_name_length: 상품명 길이, product_description_length: 상품 상세 길이, products_photos_qty: 상품 사진 개수, product_weight_g: 상품 무게(g) 를 의미한다.
products['product_category_name'].unique() == len(products['product_id'])
를 확인해보니, product_category_name의 서로 다른 값의 개수와 전체 row 개수가 동일하므로 각 상품마다 고유한 product_id를 가지고 있다.- proudct_category_name은 상품의 카테고리를 의미하는 것 같고
products[’product_category_name’].unique()
를 확인해보니, 총 73가지 종류가 있다. products.describe()
를 확인해보니 product_name_length는 최소 5 최대 76, 평균 48이다. product_description_length는 최소 4, 최대 3992, 평균 771이다. product_photos_qty는 최소 1, 최대 20, 평균 2 이다.
orders
각 컬럼명을 해석해보면 _order_id: 주문 아이디, customer_id: 고객 아이디, order_status: 주문 상태, order_purchase_timestamp: 구매 시각, order_approved_at: 주문 승인 시각, order_estimated_delivery_date: 주문 예상 시각_이다.
이 때, order_delievered_carrier_date와 order_delivered_customer_date는 정확한 의미를 파악할 수 없어 실제 데이터를 확인해보며 파악하기로 하자.
orders['order_id’].nunique()
로 확인해보니 row 개수와 동일하므로, orders에서 한 주문당 하나의 유니크한 order_id를 가지고 있다.
order_status의 각 의미 파악하기
orders[’order_status’].unique()
로 확인해보니 orders에서 order_status는 총 8가지 상태가 있다 : 'delivered', 'invoiced', 'shipped', 'processing', 'unavailable', 'canceled', 'created', 'approved'
order_status 각 상태별 데이터를 확인하여 상태의 의미 파악하기
orders[order[’order_status’] == ‘created’]
를 보니 _order_approved_at_이 안채워짐orders[order[’order_status’] == ‘approved’]
를 보니 _order_approved_at_이 채워짐- orders[order[’order_status’] == ‘processing’]을 보니 order_delievered_carrier_date, order_delivered_customer_date 둘 다 안 채워짐
- orders[order[’order_status’] == ‘invoiced’]을 보니 order_delievered_carrier_date, order_delivered_customer_date 둘 다 안 채워짐
- orders[order[’order_status’] == ‘shipped’]를 보니 order_delievered_carrier_date가 채워짐, order_delivered_customer_date는 안채워짐
- orders[order[’order_status’] == ‘delivered’]를 보니 order_delievered_carrier_date, order_delivered_customer_date 둘 다 채워짐
- order_estimated_delievery_date 배송 예상 시간인데 주문할 때부터 채워지는 값으로 파악할 수 있다.
- order_delievered_carrier_date는 배송될 때부터 채워진 값이다. 그래서 배송 보낸 날짜이라고 유추할 수 있다.
- order_delievered_customer_date는 shipped일때는 없다가 delivered일 때 채워진다. 그래서 고객이 배송을 받은 날짜라고 유추할 수 있다.
데이터가 채위지는 순서로 보아 order_status는 대략 created -> approved -> processing -> invoiced -> shipped -> delivered 이며 각각 주문됨, 승인됨, 처리중, 송장발급됨, 배송시작, 배송완료됨 을 의미한다.
order_items
order_items[’order_item_id’].unique()
를 확인해보니 1부터 21까지 가능하다.order_items[’order_id’].nunique()
를 확인해보니, 고유하지 않다!order_items[order_items[’order_item_id’] == 21]
에서 나오는 order_id 8272b63d03f5f79c56e9e4120aec44ef로order_items[order_items['order_id'] == '8272b63d03f5f79c56e9e4120aec44ef']
와 같이 필터링해보니, 같은 order_id에 order_item_id로 구분되는 여러개의 아이템이 담긴 것을 확인할 수 있다.- order_items 에서는 하나의 order_id에서 여러 개의 물건을 샀을 때 그 정보를 알려주는 테이블이다.
payments
payments['payment_sequential'].unique()
를 확인해보니 1부터 29까지 가능하다.- 대부분의 데이터는 1-2 인 거 같은 데 29는 특별한 데이터인 것 같으니 필터링해서 보자.
payments[payments['payment_sequential'] == 29
에서 나오는 order_id fa65dad1b0e818e3ccc5cb0e39231352로 필터링해본다.payments[payments['order_id'] == 'fa65dad1b0e818e3ccc5cb0e39231352']
- 한 order_id에서 1부터 29까지의 각기 다른 구매액을 가지는 것을 확인할 수 있다.
- 따라서 payments은 한 주문을 몇 개의 다른 구매 방법으로 나누어서 결제한 정보를 담고 있다.
- payment_installments: 할부를 몇개월 했는 지에 대한 정보를 알려준다.
- payment_sequential: 하나의 order에서 결제를 몇 번째로 나누어서 구매했는지 알려준다.