EDA

Data Wrangling

bomishot 2023. 2. 26. 18:04

품질, 구조적 문제   re    str접근자
merge   concat    melt <->pivot_table

 

앞으로 만나게 될 데이터셋은 깔끔하게 정리되어 있지 않은 경우가 많을 것이다.

하지만 Garbage In Garbage Out이라는 말처럼 이렇게 정리되어 있지 않은 데이터셋을 그대로 사용하는 것은 많은 문제를 야기한다.

Data Wrangling을 통해 데이터셋을 분석하기 좋은 깔끔한 형태로 정제, 변형해보자.
또한, 데이터셋의 크기, 확인하고자 하는 것의 범위 등에 따라 어떤 방법을 선택하는 것이 효율적인지 판단해보자.

 

EDA - 데이터를 이해하는 과정

Data Wrangling - raw data를 분석에 용이하도록 정제, 변형하는 과정

어떤 목적인지, 데이터가 어떤 상태인지에 따라 무엇을 먼저할지 생각해볼 수 있음.

-> EDA를 통해 시각화했을 때, 데이터 내 어떤 부분을 제거해야하는지가 더 명확하게 보일 수 있고, 먼저 깔끔하게 정리하는 Data Wrangling이 오히려 insight를 발견하기 쉽게 만들 수도 있음!

 

 

Data Wrangling

  • Data Wrangling에 어떠한 작업이 포함되나?
    • Data Aggregation
    • Data 시각화
    • predict를 위한 통계 모델 훈련
  • 데이터 분석에, Data Cleaning이 중요한 이유
    • Data may have the following impurities:
      • missing values
      • outliers
      • non-standard values
      • data quality

  1. 데이터 수집
  2. 데이터 탐색
    • 탐색 방법
      • 시각적 탐색
      • 프로그래매틱 탐색 → info()같은 코드를 통해, 전체적 데이터 확인
    1. 데이터 품질의 문제
      • 데이터에서 content issue 발생 → such as duplicatied, missing, inaccurate
      • 해결방안 : 정규표현식 활용
    2. 데이터 구조의 문제
      • 아래의 tidy data(= 분석하기 좋은 데이터)의 조건을 만족하지 않는 경우
        • 각 변수는 하나의 열 구성
        • 각 관측치는 하나의 행 구성
        • 각 유형의 관측 단위가 표 구성
      • 품질 고려 문제 해결 (missing vlaue → duplicates) → 구조적 문제 해결

          3. 데이터 정제

Long Format (=tidy data) - Wide Format

    • melt : (wide->long)
    • pivot
    • pivot_table : (long->wide) groupby처럼 그룹분석하지만, 최종적으로는 pivot 명령처럼 pivot table 생성
    • (인수의 순서가 pivot과 다른 점 유의)melt ↔ pivot_table

경구용_인슐린, 주사제_인슐린 column: 시작 복용량 - 마지막 복용량 &larr; 2개의 변수(variables) 인슐린 종류에 대한 새로운 column 생성 필요

# 경구용_인슐린, 주사제_인슐린 분리 후 u자 제거 
pd.melt(
    insuline_test_clean, 
    id_vars=['이름', '혈당수치_시작', '혈당수치_끝', '혈당수치_변화'],
    var_name='인슐린_종류', # id를 제외한 컬럼 이름이 카테고리화 됨
    value_name='투여량' # id를 제외한 컬럼 값들이 모이는 컬럼의 이름
    )

insuline_test_clean[insuline_test_clean.투여량 != "-"]

['투여량'].str.split(" ", 1) 
# 스페이스 기준으로 최대 1번만 분리 >> 리스트 형태로 반환

# 투여량
insuline_test_clean['시작_투여량'], insuline_test_clean['마지막_투여량'] = 
insuline_test_clean['투여량'].str.split(' - ', 1).str

# [41u, 48u] >> str을 사용하지 않고 하나의 변수에 할당하면 리스트의 형태로 출력
# 변수 개수와 리스트 내 값 길이를 동일하게 해주어야 각각 할당될 수 있다.

 

DataFrame 합치는 방법

  • contcat, merge, join
    • concat : DataFrame 붙이기 (기준 열을 사용하지 않고 단순히 데이터 연결)(default : outer, axis=0)
      • outer : 합집합
      • inner : 교집합
      • pd.concat([df1, df2], axis=1, join=’inner’)
    • merge : 공통열을 기준으로 DataFrame 병합
      • how=”outer” 옵션시, 어느 한쪽에라도 없는 데이터가 있는 경우 NaN값 지정
      • (how : 조인방법) how=’left’, how=’right’
      • pd.merge(df1, df2, how=’inner’, on=None)가 default
    • join : DataFrame 결합
      • merge와 비슷하지만, 행 인덱스를 기준으로 결합한다는 차이점.
      • df.join(other, lsuffix = '_caller', rsuffix = '_other')

 

정규표현식 / str 접근

  • 공백 제거하기 : re.sub(pattern, ' ', text)
# 공백 제거하기
text = "   This is a text with    many    spaces.   "
pattern = r"\s+"
re.sub(pattern, " ", text)
>> "This is a text with many spaces."
  • 전화번호 추출하기 : re.search(patter, text).group() / re.findall(pattern, text)
text = "My phone number is 010-1234-5678"
pattern = r"\b\d{2,3}-\d{3,4}-\d{4}\b"
match = re.search(pattern, text)
print(match.group()) 
>> 010-1234-5678

# re.search() : 문자열에서 첫 번째로 매칭되는 패턴 찾음
# match 변수는 'matchobject'객체를 가리키는 변수기 때문에,
# match.group(n) : n번째 그룹에 매칭되는 문자열 반환

# \b: 단어의 경계를 나타내는 메타 문자
# \d{2,3}: 2~3자리의 숫자
# \d{4}: 4자리의 숫자
# 문자열에 여러 개의 URL이 있을 경우 : `re.findall()`로 모든 url추출
text = "Visit my websites at https://www.example.com and http://www.example.org"
pattern = r"https?://[A-Za-z0-9./]+"
matches = re.findall(pattern, text)
print(matches)  
>> ['https://www.example.com', 'http://www.example.org'] # 리스트로 반환
  • URL 추출하기
text = "Visit my website at https://www.example.com"
pattern = r"https?://[A-Za-z0-9./]+"
match = re.search(pattern, text)
print(match.group(0))  
>> https://www.example.com

# https? => ? : 's'가 있을 수도, 없을수도 있다는 뜻. https, http
# [A-Za-z0-9./]+: 대문자, 소문자, 숫자, ".", "/", 그리고 "+" 문자 중 하나 이상이 1번 이상 등장
patients_clean.나이.str.extract('(\d+)').astype('int')
patients_clean.나이.str.replace(r'[^a-zA-Z]', '', regex=True)
# regex=True : 정규표현식으로 보겠다는 의미.

# str >> Series 전체 적용

# \d >> 숫자 = [0-9]
# \D >> 숫자 제외 문자 = [^0-9]

# + >> 하나 이상의 문자가 반복되는 패턴
# \d+ >> 하나 이상의 숫자가 반복되는 패턴

 

 

참고자료

[Tidying Datasets in Python

Originally in R. Now in Python with Pandas.

https://medium.com/@aaronmak/tidying-datasets-in-python-8634f39159bc

)](https://medium.com/@aaronmak/tidying-datasets-in-python-8634f39159bc)

  • 정규표현식

[

Python, Machine & Deep Learning

Python, Machine Learning & Deep Learning

)https://greeksharifa.github.io/%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D(re)/2018/07/20/regex-usage-01-basic/

)](https://greeksharifa.github.io/%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D(re)/2018/07/20/regex-usage-01-basic/)

  • str

[

스트링 접근자: str accessor

https://gils-lab.tistory.com/95

)](https://gils-lab.tistory.com/95)

참고사이트 : 데이터 사이언스 스쿨

[

4.7 피봇테이블과 그룹분석 — 데이터 사이언스 스쿨

https://datascienceschool.net/01%20python/04.07%20%ED%94%BC%EB%B4%87%ED%85%8C%EC%9D%B4%EB%B8%94%EA%B3%BC%20%EA%B7%B8%EB%A3%B9%EB%B6%84%EC%84%9D.html

](https://datascienceschool.net/01%20python/04.07%20%ED%94%BC%EB%B4%87%ED%85%8C%EC%9D%B4%EB%B8%94%EA%B3%BC%20%EA%B7%B8%EB%A3%B9%EB%B6%84%EC%84%9D.html)

 

  • pd.set_option(’display.max_columns’, 숫자) : 출력할 열의 최대 개수
  • pd.set_option(’display.max_colwidth’, 숫자) : 출력할 열의 최대 너비