Data Analysis/Python

[Pandas] 데이터 기능 대체하기

太热了 2022. 5. 14. 11:30

엑셀을 가장 많이 사용하는 사람으로써, 엑셀은 정말 유용하고 편리한 툴이다.

그러나 유일한 단점은 느리다.. 그래서 대용량의 데이터를 다루기에는 부적합하고, 엑셀의 스크립트 언어인 VBA는 불필요할 정도로 복잡하다! 이를 위해서 우리 파이썬을 활용해 엑셀의 주요 기능을 효율적으로 대체하는 방법을 학습해보고자 한다.

데이터 기능 대체하기

엑셀에서 제공하는 정렬, 필터, 텍스트 나누기, 중복된 항목 제거 등의 데이터 기능

  • Sort_values 함수에 대한 이해

: 데이터 정렬은 하나 이상의 열을 기준으로 오름차순 혹은 내림차순으로 정렬하는 것
: by, ascending 인자가 있음!
(by = 정렬 기준이 되는 열 이름 혹은 열 이름 목록을 설정하는 인자 [ex. df.sort_values(by=['A','B']))
(ascending = 오름차순 여부를 설정하는 인자, 지정하지 않으면 오름차순으로 정렬[True면 오름차순, False면 내림차순])

import pandas as pd 
df = pd.read_excel("http://www.innocoding.co.kr/python_4-1.xlsx")

print('[체중열을 기준으로 정렬]')
print(df.sort_values(by = '체중').to_html()) 

print('[신장과 체중열을 기준으로 정렬]')
print(df.sort_values(by = ['신장', '체중']).to_html()) 
import pandas as pd 
df = pd.read_excel("http://www.innocoding.co.kr/python_4-1.xlsx")

print('[체중열을 기준으로 오름차순정렬]')
print(df.sort_values(by = '체중', ascending = True).to_html()) 

print('[체중열을 기준으로 내림차순정렬]')
print(df.sort_values(by = '체중', ascending = False).to_html()) 

  • 마스크를 이용한 인덱싱

: 비교 연산의 결과는 항상 bool 배열이므로, 이를 이용하여 특정 조건을 만족하는 값이나 행만 가져올 수 있는데, 이를 마스크를 이용한 인덱싱이라고 부른다.
: Series[조건], DataFrame[조건] 으로 수행가능
: numpy의 logical_and()함수 와 logical_or()함수를 사용하면 두 개 이상의 조건을 효과적으로 결합 가능
- np.logical_and(조건1, 조건2) => 조건1과 조건2를 모두 만족하는 경우에만 True반환
- np.logical_or(조건1, 조건2) => 조건1과 조건2 둘 중 하나 이상을 만족하는 경우에 True 반환

import numpy as np
print(np.logical_and([True, True, False, False], [True, False, True, False]))
print(np.logical_or([True, True, False, False], [True, False, True, False]))

logical_and()함수의 경우에는 같은 인덱스의 값이 둘다 True일경우에만 True 를 반환하고,
logical_or()함수에서는 같은 인덱스의 두개의 값중 하나만 True이면 True 를 반환

: .str에 속한 함수 활용시, 텍스트와 관련된 조건 생성 가능 - contains 함수

import pandas as pd
series = pd.Series(['A-1234', 'A-3284', 'B-4312', 'B-3104'])
condition = series.str.contains('A')
print(condition)

#0 True
#1 True
#2 False
#3 False
#type: bool

  • 필터링 기능 대체하기

: 마스크를 이용한 인덱싱 방법 활용하여 월별 판매량을 나타내는 데이터에서 판매량이 200이상 300미만인 월을 찾는 실습

import pandas as pd
import numpy as np
df = pd.read_csv('http://www.innocoding.co.kr/python_4-2.csv', engine = "python")

cond1 = df['판매량'] >= 200
print(df[cond1])

cond2 = df['판매량'] < 300
print(df[cond2])

cond = np.logical_and(cond1, cond2)
print(df[cond])

세 개 이상의 조건에 대해, np.logical_and를 적용하기 위해서는 np.logical_and(np.logical_and(cond1, cond2), cond3)와 같이 logical_and()함수를 중첩하여 사용

: 문자열함수를 사용하여 은행 지점 목록 데이터에서 수원에 있는 신한은행을 찾는 실습

import pandas as pd
import numpy as pd 
df = pd.read_excel('http://www.innocoding.co.kr/python_4-3.xlsx')

cond1 = df['은행명'] == '신한'
cond2 = df['주소'].str.contains('수원시')
cond = np.logical_and(cond1, cond2)

print('수원에 있는 신한은행 수:', sum(cond))
print(df[cond].to_html())

cond1 = df['은행명'] == '신한'
- '은행명'열 에 '신한'이라고 입력되어있는지 여부(Bool:True,False)가 cond1로 지정

cond2 = df['주소'].str.contains('수원시')
- '주소'열의 데이터 중 '수원시'라는 문자열이 포함되었있는지 여부(Bool:True,False)가 cond2로 지정

cond = np.logical_and(cond1, cond2)
- logical_and()함수에 의해 위 두가지의 조건이 모두 만족하는지 여부(Bool:True,False)가 cond로 지정

  • .str 속성과 그 함수

: expand를 True로 설정하여 배열의 값을 바탕으로 dataframe 생성도 가능

import pandas as pd
series = pd.Series(['16:40', '21:32', '19:00', '20:04'])
df = series.str.split(':', expand = True)

print(df.to_html())
  • 텍스트 나누기

: 하이픈으로 구분되어 있는 날짜 분리, 기존 데이터와 결합하는 실습

import pandas as pd
df = pd.read_csv('http://www.innocoding.co.kr/python_4-4.csv', engine = "python")

date_df = pd.DataFrame(
  	df['날짜'].str.split('-', expand = True).values,
	columns = ['연도', '월', '일']
)

merged_df = pd.concat([date_df, df], axis = 1).drop('날짜', axis = 1)
print(merged_df)

.str.split(expand = True) 함수를 쓰면 컬럼명이 0, 1, … 와 같이 설정되므로, .values를 이용하여 컬럼명이 있는 DataFrame(date_df)으로 다시 만든 것! Pandas의 concat 함수는 둘 이상의 DataFrame을 이어 붙여주는 함수로, axis = 1로 설정하면 열 단위로 이어 붙인다. 연도, 월, 일 컬럼이 새로 생성되었으므로, 날짜 컬럼이 필요가 없어져 .drop 함수를 이용하여 날짜 컬럼을 삭제하였다.

  • .drop_duplicates 함수

: 중복 제거 함수
: subset 인수 사용하여 중복된 행을 판다하는데 사용되는 기준 열(집합) 결정 가능
- df.drop_duplicates(subset = ['A','B'])

import pandas as pd 
df = pd.DataFrame(
  	{
	  	'A': ['A1', 'A1', 'A1', 'A2', 'A2', 'A2'],
		'B': ['B1', 'B1', 'B2', 'B2', 'B2', 'B3'],
		'C': ['C1', 'C1', 'C1', 'C2', 'C2', 'C3']
	}
)

print('[중복제거]',df.drop_duplicates().to_html())
print('[A열을 기준으로 중복제거]',df.drop_duplicates(subset = ['A']).to_html())
print('[A,B열을 기준으로 중복제거]',df.drop_duplicates(subset = ['A', 'B']).to_html())