[Python pandas] 대용량 데이터 전처리 팁

hwwwa·2022년 1월 17일
0

🐼 Python

목록 보기
10/18

참고로 대용량 데이터와 빅데이터는 다르다.

필요 없는 변수 생성 지양

  • 분산컴퓨팅을 하지 않고, 오직 컴퓨터 하나로 대용량 데이터 전처리를 진행해야 한다면 변수 생성(초기화)을 할수록 RAM이 가득차 에러가 뜰 것이며 for 문의 속도도 현저히 떨어지게 됨

사용이 끝난 변수는 파일로 저장하거나 RAM에서 삭제

  • python의 변수 삭제 명령어는 del

CSV 파일 데이터를 청크 크기로 읽어오기

  • 100만개 이상이 넘어가는 row를 가진 데이터셋을 불러온다면 너무 무거워져서 속도가 매우 느려지게 됨
  • pandas.read_csv에서 chunksize라는 매개변수 활용 가능
  • 로컬 메모리에 맞추기 위해 한 번에 DataFrame으로 읽어 올 행의 수를 지정 가능
df_chunk = pd.read_csv(r'../input/data.csv', chunksize=1000000)

필요하지 않은 column을 필터링

  • 시간 절약 및 메모리 절약을 위해 필요하지 않은 열을 필터링하여 불러오기
df = df[['col_1','col_2', 'col_3', 'col_4', 'col_5', 'col_6']]
  • pandas.read_excel에서 usecols라는 매개변수 활용 가능
df = pd.read_excel(filename, usecols = "C:F", engine='openpyxl')

열의 dtypes 변경

  • pandas 데이터 열을 다른 타입으로 변경하는 가장 간단한 방법은 astype() 함수를 사용하는 것
  • 집중 분석이나 계산을 위한 대용량 데이터가 있는 경우 데이터 유형을 변경하여 필요한 비트를 줄이는 것은 메모리 절약에 큰 도움이 될 수 있음
# Change the dtypes (int64 -> int32)
df[['col_1','col_2', 'col_3', 'col_4', 'col_5']]
	= df[['col_1', 'col_2', 'col_3', 'col_4', 'col_5']].astype('int32')

# Change the dtypes (float64 -> float32)
df[['col_6', 'col_7', 'col_8', 'col_9', 'col_10']] 
	= df[['col_6', 'col_7', 'col_8', 'col_9', 'col_10']].astype('float32')
  • 위 코드 처럼 각 컬럼의 데이터 형식을 지정해줄 수 있지만, 각 컬럼의 데이터 형식을 모르는 경우 코드에서 해결하는 방법도 있음
  • 데이터를 불러왔지만 크기를 줄이고 싶은 경우
df = pd.read_csv(data_path)
data_types = check_dtypes(df)
df = df.astype(data_types)
  • 데이터가 커서 불러오지도 못하는 경우
columns = ps.read_csv(data_path, rows=0).columns
data_types = {col : check_dtypes(df[col]) for col in columns}
df = pd.read_csv(data_path, dtype = data_types)

코드화

  • 문자열로 된 데이터를 숫자/영어로 코드화하여 데이터를 크게 축소시킬 수 있음
    • ex) 서울특별시→11, 대구광역시→45

기타 pandas의 유용한 함수들

select_dtypes(include = [], exclude = [])

  • column의 데이터 타입별로 뽑아낼 수 있음
  • 정형 데이터만 뽑아서 보고 싶을 때 컬럼명을 하나하나 입력할 필요가 없어짐
df.select_dtypes(include=['object', 'int64'])
df.select_dtypes(exclude=['bool', 'int64'])

isin()

  • for 문 보다는 apply가 살짝 더 빠르고 isin은 훨씬 빠름 (조건에 따라 다를 수 있지만)
df = DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']})

print(df.isin([1, 3, 12, 'a']))
#       A      B
# 0  True   True
# 1 False  False
# 2  True  False

print(df[df['A'].isin([1, 3, 12])])
#     A   B
# 0   1   a
# 2   3   f

groupby() & size()

  • SQL문의 group by절과 집계함수 count()의 기능을 해줌
  • 아래 예시는 id별, day별로 day의 count 값을 구하는 코드
  • 리턴 값은 pandas.core.series.Series이며 id와 day로 멀티인덱싱 됨
temp = df.groupby(['user_id', 'day']).size()
  • 위의 리턴 값을 DataFrame으로 변환 하기
df2 = pd.DataFrame(data=temp.keys().tolist(), columns=['user_id', 'day'])
df2['cnt'] = temp.values

0개의 댓글