캐글의 다음 데이터를 불러오려고 하는데, 데이터의 용량이 너무 커서 read_csv로 불러와지지 않았다.
https://www.kaggle.com/datasets/mkechinov/ecommerce-behavior-data-from-multi-category-store
이럴 때 parquet를 이용하면 된다!
anaconda prompt를 관리자 권한으로 실행하여 다음 코드를 실행해주면 된다.
conda install -c conda-forge fastparquet
conda install -c conda-forge pyarrow
위 캐글에서 csv 데이터를 다운받아 전체를 불러오려고 하면 엄청나게 오랜 시간이 걸릴 것이다. 이럴 때 pandas의 read_csv의 skiprows와 nrows를 활용하면 된다. 나는 42,448,764개의 행 중 35,373,970 ~ 42,448,763번째의 행, 총 7,074,794개의 행을 불러오려고 한다.
컬럼으로 사용할 이름을 리스트로 입력
df = pd.read_csv('../data/2019-Oct.csv', skiprows=35373971, header=None)
df.shape
결과:
(7074794, 9)
df.info()
결과:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7074794 entries, 0 to 7074793
Data columns (total 9 columns):
# Column Dtype
--- ------ -----
0 0 object
1 1 object
2 2 int64
3 3 int64
4 4 object
5 5 object
6 6 float64
7 7 int64
8 8 object
dtypes: float64(1), int64(3), object(5)
memory usage: 485.8+ MB
col_name = pd.read_csv('../data/2019-Oct.csv', nrows=2).columns.to_list()
col_name
결과:
['event_time',
'event_type',
'product_id',
'category_id',
'category_code',
'brand',
'price',
'user_id',
'user_session']
df.columns = col_name
df.head()
메모리 부담을 줄이기 위해 데이터 타입을 변경해주고, 분석에 쓰지 않을 user_session 컬럼을 삭제해주었다.
# user_session 컬럼 삭제
df = df.drop(['user_session'], axis=1)
# event_time 컬럼 -> date 타입으로 변경
df['event_time'] = pd.to_datetime(df['event_time'])
# int 타입으로 시작하는 컬럼은 unsigned 타입으로 변경
# float 타입으로 시작하는 컬럼은 float 타입으로 변경
# object 타입으로 시작하는 컬럼은 category 타입으로 변경
for col in df.columns:
type_name = df[col].dtypes.name
if type_name.startswith('int'):
df[col] = pd.to_numeric(df[col], downcast='unsigned')
elif type_name.startswith('float'):
df[col] = pd.to_numeric(df[col], downcast='float')
elif type_name.startswith('object'):
df[col] = df[col].astype('category')
이렇게 변경한 후, 데이터프레임의 요약 정보를 보면 다음과 같다.
df.info()
결과:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7074794 entries, 0 to 7074793
Data columns (total 8 columns):
# Column Dtype
--- ------ -----
0 event_time datetime64[ns, UTC]
1 event_type category
2 product_id uint32
3 category_id uint64
4 category_code category
5 brand category
6 price float32
7 user_id uint32
dtypes: category(3), datetime64[ns, UTC](1), float32(1), uint32(2), uint64(1)
memory usage: 216.1 MB
처음에 불러왔을 때 485.8+ MB였던 데이터가 216.1 MB로 줄어든 것을 확인할 수 있다.
이제 데이터 용량을 줄이기 위해 csv가 아닌 parquet로 저장해볼 것이다.
file_path_parquet = 'df.parquet.gzip'
df.to_parquet(file_path_parquet, compression='gzip')
저장된 데이터프레임을 확인해보면 68.1 MB로 비록 전체 행의 1/6만 불러왔지만 5.67기가 였던 원래 데이터 용량보다 확연하게 줄어든 것을 확인할 수 있다. 나머지 행들도 이런 과정을 거친 후 parquet로 저장하고, 나중에 6개의 파일을 한번에 합치면 되지 않을까 싶다.
[원본데이터]
[parquet로 저장한 데이터]