Pandas 란? (2)

쓰리원·2023년 6월 25일

Data Analysis

목록 보기
3/4
post-thumbnail

1. 데이터 정리 및 전처리

1-1. 결측값 처리

데이터 분석에서 결측값은 종종 문제를 일으킬 수 있으므로 미리 처리해야 한다. pandas는 결측값을 처리하기 위한 여러 가지 방법을 제공한다.

  • 결측값 제거 (dropna())
    • 행 또는 열을 기준으로 제거할 수 있다.
# 결측값이 있는 행 제거
df_cleaned = df.dropna()
print(df_cleaned)
  • 결측값 대체 (fillna())
    • 평균값, 중간값, 또는 고정된 값을 결측값에 채울 수 있다.
# 결측값을 0으로 대체
df_filled = df.fillna(0)
print(df_filled)

# 결측값을 평균값으로 대체
df['Age'] = df['Age'].fillna(df['Age'].mean())
print(df)

1-2. 중복 데이터 처리

  • 중복값 확인 (duplicated())
data = {'Name': ['Alice', 'Bob', 'Alice', 'David'],
        'Age': [25, 30, 25, 40]}

df = pd.DataFrame(data)

# 중복값 확인
print(df.duplicated())

0    False
1    False
2     True
3    False
dtype: bool
  • 중복값 제거 (drop_duplicates())
    Name  Age
0  Alice   25
1    Bob   30
2  Alice   25
3  David   40

# 중복값 제거
df_no_duplicates = df.drop_duplicates()
print(df_no_duplicates)

    Name  Age
0  Alice   25
1    Bob   30
3  David   40

1-3. 데이터 정렬

  • 값을 기준으로 정렬 (sort_values())
    • 특정 열의 값을 기준으로 데이터를 정렬할 수 있다.
    • 기본적으로 오름차순으로 정렬되며, 내림차순은 ascending=False 옵션을 사용한다.
import pandas as pd

# 예제 데이터
data = {
    'Name': ['철수', '영희', '민수', '지수'],
    'Age': [25, 30, 20, 28]
}

df = pd.DataFrame(data)

print(df)

  Name  Age
0   철수   25
1   영희   30
2   민수   20
3   지수   28

# Age를 기준으로 오름차순 정렬
df_sorted = df.sort_values(by='Age')
print(df_sorted)

  Name  Age
2   민수   20
0   철수   25
3   지수   28
1   영희   30

# Age를 기준으로 내림차순 정렬
df_sorted_desc = df.sort_values(by='Age', ascending=False)
print(df_sorted_desc)

  Name  Age
1   영희   30
3   지수   28
0   철수   25
2   민수   20
  • 인덱스를 기준으로 정렬 (sort_index())
# 순서가 섞인 인덱스를 가진 DataFrame
data = {
    'Name': ['철수', '영희', '민수', '지수'],
    'Age': [25, 30, 20, 28]
}

df = pd.DataFrame(data, index=[3, 1, 4, 2])
print(df)

  Name  Age
3   철수   25
1   영희   30
4   민수   20
2   지수   28

# 인덱스를 기준으로 오름차순 정렬
df_sorted_index = df.sort_index()
print(df_sorted_index)

  Name  Age
1   영희   30
2   지수   28
3   철수   25
4   민수   20

# 인덱스를 기준으로 내림차순 정렬
df_sorted_index_desc = df.sort_index(ascending=False)
print(df_sorted_index_desc)

  Name  Age
4   민수   20
3   철수   25
2   지수   28
1   영희   30

1-4. 데이터 필터링

  • 조건부 필터링
    • 특정 조건에 맞는 데이터만 선택한다.

      # Age가 30 이상인 데이터 필터링
      df_filtered = df[df['Age'] >= 30]
      print(df_filtered)
  • 여러 조건을 사용한 필터링
    • 여러 조건을 결합하여 데이터를 필터링할 수 있다.

    • 조건을 결합할 때는 논리 연산자 (&, |)를 사용한다.

      # Age가 30 이상이고, Name이 'Bob'인 데이터 필터링
      df_filtered = df[(df['Age'] >= 30) & (df['Name'] == 'Bob')]
      print(df_filtered)

2. 데이터 변형 및 조작

2-1. 데이터 변형

pandas에서 데이터 변형을 수행할 때, apply(), map(), lambda 함수는 매우 강력한 도구이다. 이 함수들을 사용하면 DataFrame 또는 Series의 각 요소에 대해 원하는 연산을 수행할 수 있다.

  • apply() 함수

    • apply()는 DataFrame이나 Series의 각 요소에 함수를 적용할 때 사용된다.

    • 특히 열(column) 단위나 행(row) 단위로 복잡한 연산을 적용할 때 유용하다.

      import pandas as pd
      
      data = {
          'Name': ['Alice', 'Bob', 'Charlie', 'David'],
          'Score': [85, 90, 78, 92]
      }
      
      df = pd.DataFrame(data)
      
      # 각 점수에 10점을 더하는 함수 적용
      df['AdjustedScore'] = df['Score'].apply(lambda x: x + 10)
      print(df)
      
              Name  Score  AdjustedScore
      0   Alice     85            95
      1     Bob     90           100
      2 Charlie     78            88
      3   David     92           102
  • map() 함수

    • map() 함수는 주로 Series 객체에 적용되며, 각 요소를 특정 값으로 매핑하거나 변환할 때 사용된다.

    • 특정 값을 다른 값으로 대체할 때 많이 사용된다.

      # 성별 데이터 변환 예시
      gender_data = pd.Series(['Male', 'Female', 'Female', 'Male'])
      
      # 성별을 숫자로 변환
      gender_numeric = gender_data.map(lambda x: 0 if x == 'Male' else 1)
      print(gender_numeric)
      
      0    0
      1    1
      2    1
      3    0
      dtype: int64

2-2. 데이터 조작

  • merge() 함수
    • pandas의 merge() 함수는 SQL의 JOIN과 유사하게 두 개의 DataFrame을 특정 열을 기준으로 결합한다.

    • 다양한 방법으로 조인할 수 있으며, left, right, inner, outer 조인이 가능하다.

      # 두 개의 데이터프레임 생성
      df1 = pd.DataFrame({'CustomerID': [1, 2, 3], 'Product': ['Laptop', 'Mouse', 'Keyboard']})
      df2 = pd.DataFrame({'CustomerID': [2, 3, 4], 'Location': ['USA', 'Canada', 'Mexico']})
      
      # CustomerID를 기준으로 두 DataFrame 결합 (inner join)
      df_merged = pd.merge(df1, df2, on='CustomerID', how='inner')
      print(df_merged)
      
             CustomerID       Product    Location
      0           2            Mouse      USA
      1           3            Keyboard   Canada
  • concat() 함수
    • concat() 함수는 여러 DataFrame을 위아래로 또는 좌우로 결합할 때 사용된다. 이때 행을 추가하는 경우 axis=0, 열을 추가하는 경우 axis=1을 사용한다.

      # 두 개의 데이터프레임을 세로로 연결
      df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
      df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
      
      df_concat = pd.concat([df1, df2], axis=0)
      print(df_concat)
      
          A   B
      0  A0  B0
      1  A1  B1
      0  A2  B2
      1  A3  B3
  • join() 함수
    • join()은 두 개의 DataFrame을 인덱스를 기준으로 결합할 때 사용된다.

    • 주로 인덱스가 동일한 경우에 사용된다.

      # 예시 데이터프레임 생성
      df1 = pd.DataFrame({'A': ['A0', 'A1']}, index=['K0', 'K1'])
      df2 = pd.DataFrame({'B': ['B0', 'B1']}, index=['K0', 'K1'])
      
      # join을 이용해 인덱스를 기준으로 결합
      df_join = df1.join(df2)
      print(df_join)
           A   B
      K0  A0  B0
      K1  A1  B1

2-3. 데이터 피벗 및 변형

  • pivot() 함수
    • pivot() 함수는 데이터프레임을 재구조화 하여 행, 열, 값으로 표현할 수 있는 형식으로 변환한다.
    • 주로 index, columns, values를 지정하여 사용한다.
      data = {'Date': ['2024-01-01', '2024-01-01', '2024-01-02'],
              'City': ['New York', 'Los Angeles', 'New York'],
              'Temperature': [55, 68, 52]}
      
      df_weather = pd.DataFrame(data)
      
      # pivot을 이용해 날짜별 도시 온도 정리
      df_pivot = df_weather.pivot(index='Date', columns='City', values='Temperature')
      print(df_pivot)
      
      City        Los Angeles  New York
      Date
      2024-01-01           68        55
      2024-01-02          NaN        52
  • pivot_table() 함수
    • pivot_table() 함수는 그룹화된 데이터를 요약하여 피벗 테이블로 변환할 수 있다.

      aggfunc 옵션을 사용하여 합계, 평균 등의 연산을 할 수 있다.

      sales_data = {
          'Product': ['A', 'B', 'A', 'B'],
          'Sales': [100, 150, 200, 250],
          'Region': ['North', 'South', 'North', 'South']
      }
      
      df_sales = pd.DataFrame(sales_data)
      
      # pivot_table을 이용해 지역별, 상품별 총 판매량 요약
      df_pivot_table = df_sales.pivot_table(values='Sales', index='Region', columns='Product', aggfunc='sum')
      print(df_pivot_table)
      
      Product     A      B
      Region
      North    300.0    NaN
      South      NaN  400.0
  • melt() 함수
    • melt() 함수는 데이터프레임을 넓은 형식에서 긴 형식으로 변환하는 데 사용된다.
      이는 데이터를 열 기준으로 "녹여" 변수와 값 형태로 변환다.
      df_wide = pd.DataFrame({
          'ID': [1, 2, 3],
          'Math': [85, 90, 88],
          'English': [78, 85, 90]
      })
      
      # melt를 이용해 긴 형식으로 변환
      df_melt = pd.melt(df_wide, id_vars=['ID'], value_vars=['Math', 'English'], var_name='Subject', value_name='Score')
      print(df_melt)
      
      
         ID  Subject  Score
      0   1     Math     85
      1   2     Math     90
      2   3     Math     88
      3   1  English     78
      4   2  English     85
      5   3  English     90

3. 데이터 그룹화 및 집계

3-1. 데이터 그룹화

  • groupby() 함수
    • 데이터를 특정 기준에 따라 그룹화하여 집계 연산을 수행한다. 이를 통해 데이터의 패턴을 발견하거나 요약 통계를 얻는 데 매우 유용하다.
    • 기본적인 그룹화groupby()는 주어진 열을 기준으로 데이터를 그룹화하고, 그 결과에 대해 다양한 집계 연산을 적용할 수 있다.
      import pandas as pd
      
      data = {
          'Department': ['HR', 'IT', 'HR', 'Finance', 'IT', 'Finance'],
          'Salary': [50000, 60000, 52000, 80000, 65000, 90000]
      }
      df = pd.DataFrame(data)
      
      # 부서별로 평균 급여 계산
      grouped = df.groupby('Department')['Salary'].mean()
      print(grouped)
      
      Department
      Finance    85000.0
      HR         51000.0
      IT         62500.0
      Name: Salary, dtype: float64
  • 여러 열을 기준으로 그룹화
    • 여러 열을 기준으로 그룹화할 수도 있다. 이 경우, 그룹화된 데이터의 각 고유한 값 조합에 대해 집계 연산이 적용된다.
      data = {
          'Department': ['HR', 'IT', 'HR', 'Finance', 'IT', 'Finance'],
          'Location': ['New York', 'New York', 'Chicago', 'Chicago', 'New York', 'Chicago'],
          'Salary': [50000, 60000, 52000, 80000, 65000, 90000]
      }
      df = pd.DataFrame(data)
      
      # 부서와 위치별로 평균 급여 계산
      grouped = df.groupby(['Department', 'Location'])['Salary'].mean()
      print(grouped)
      
      Department  Location
      Finance     Chicago      85000.0
      HR          Chicago      52000.0
                  New York     50000.0
      IT          New York     62500.0
      Name: Salary, dtype: float64

3-2. 데이터 집계 함수

pandas에서는 그룹화된 데이터에 대해 다양한 집계 연산을 수행할 수 있다. sum(), mean(), count(), max(), min() 등이 있으며, 여러 연산을 동시에 수행할 수도 있다.

  • 집계 연산 적용
    • agg() 함수는 그룹화된 데이터에 대해 원하는 집계 연산을 적용하여 요약 통계를 얻을 수 있다.

      # 부서별로 총 급여, 평균 급여, 직원 수 계산
      aggregated = df.groupby('Department').agg({
          'Salary': ['sum', 'mean', 'count']
      })
      print(aggregated)
      
                 Salary
                    sum     mean count
      Department
      Finance     170000  85000.0     2
      HR          102000  51000.0     2
      IT          125000  62500.0     2
    • agg() 함수를 적용하면 하나의 그룹화된 데이터에 여러 집계 함수를 동시에 적용할 수도 있다.

      # 여러 집계 함수 적용
      df.groupby('Department')['Salary'].agg(['sum', 'mean', 'min', 'max'])
      
                   sum     mean   min   max
      Department
      Finance    170000  85000  80000  90000
      HR         102000  51000  50000  52000
      IT         125000  62500  60000  65000

3-3. 그룹화된 데이터 필터링

  • filter() 함수
    • 그룹별로 조건을 검사하여 해당 조건을 만족하는 그룹만 반환한다. 그룹화된 데이터에서 조건을 걸어 필요한 그룹만 선택할 수 있다.
# 평균 급여가 60000 이상인 부서만 선택
filtered = df.groupby('Department').filter(lambda x: x['Salary'].mean() >= 60000)
print(filtered)

  Department  Location  Salary
3   Finance    Chicago   80000
5   Finance    Chicago   90000
1   IT         New York   60000
4   IT         New York   65000

3-4. 그룹화된 데이터 재구성

그룹화된 데이터를 원래 형태로 재구성하거나, 필요에 따라 unstack(), stack(), reset_index()와 같은 메서드를 사용하여 데이터를 원하는 형식으로 변환할 수 있다.

  • unstack() 함수

    • 데이터를 한 차원 더 넓은 형식으로 변환한다. unstack()에 아무 인자도 넣지 않으면 기본적으로 마지막 인덱스 레벨이 열로 이동합니다.

       data = {
       'Department': ['HR', 'IT', 'HR', 'Finance', 'IT', 'Finance'],
       'Location': [
           'New York', 'New York', 'Chicago',
           'Chicago', 'New York', 'Chicago'
       ],
       'Salary': [50000, 60000, 52000, 80000, 65000, 90000]
      }
      
      df = pd.DataFrame(data)
      
      unstacked = df.groupby(['Department', 'Location'])['Salary'].mean().unstack()
      
      .unstack()                    # 마지막 인덱스 이동
      .unstack(level=-1)            # 마지막 인덱스 이동
      .unstack(level='Location')    # Location 이동
      .unstack(level=0)             # 첫 번째 인덱스 이동
      
      groupby(['Department', 'Location'])
      
      (HR, New York)       → 50000
      (HR, Chicago)        → 52000
      (IT, New York)       → 60000, 65000
      (Finance, Chicago)   → 80000, 90000
      
      부서만 보는 것이 아니라 부서와 지역의 조합으로 묶습니다.
      
      ['Salary'].mean()
      
      (HR, New York)       → 50000
      (HR, Chicago)        → 52000
      (IT, New York)       → (60000 + 65000) / 2 = 62500
      (Finance, Chicago)   → (80000 + 90000) / 2 = 85000
      
      Department  Location
      Finance     Chicago     85000.0
      HR          Chicago     52000.0
                  New York    50000.0
      IT          New York    62500.0
      Name: Salary, dtype: float64
      
      print(unstacked)
      
      Location     Chicago   New York
      Department
      Finance      85000.0        NaN
      HR           52000.0    50000.0
      IT               NaN    62500.0
      
      반대로 Department를 열로 이동하려면:
         result = (
           df.groupby(['Department', 'Location'])['Salary']
            .mean()
            .unstack(level='Department')
       )
       
      Department  Finance       HR       IT
      Location
      Chicago      85000.0  52000.0      NaN
      New York         NaN  50000.0  62500.0
  • stack() 함수

    • 데이터를 한 차원 더 긴 형식으로 변환한다.

      stacked = unstacked.stack()
      print(stacked)
      
      Department  Location
      Finance     Chicago      85000.0
      HR          Chicago      52000.0
                  New York     50000.0
      IT          New York     62500.0
      dtype: float64
  • reset_index() 함수

    • 인덱스를 리셋하여 기존 인덱스를 새로운 열로 변환한다.

      df_reset = df.groupby('Department')['Salary'].mean().reset_index()
      
      
      result = df.groupby('Department')['Salary'].mean()
      print(result)
      여기까지만 실행하면:
      
      Department
      Finance    85000.0
      HR         51000.0
      IT         62500.0
      Name: Salary, dtype: float64
      
      .reset_index() : Department를 인덱스에서 일반 열로 되돌리고, 새로운 숫자 인덱스를 만듭니다.
      print(df_reset)
      
         Department   Salary
      0   Finance     85000.0
      1   HR          51000.0
      2   IT          62500.0
profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글