ch0nny_log

[빅데이터분석] Python_47. 판다스 기본 문법 1 (1 유형) 본문

빅데이터 분석(with 아이티윌)/python

[빅데이터분석] Python_47. 판다스 기본 문법 1 (1 유형)

chonny 2024. 8. 29. 16:36

 

 

판다스(pandas) 란?

테이블 형태의 데이터를 파이썬에서 검색하기 편하도록 만들어놓은 파이썬 모듈

 

※ 장점   
1. 배우기가 쉽다.
2. 시각화 기능이 있다.
3. 데이터 검색과 통계함수들이 내장되어있다.
4. 머신러닝 기능들             이 내장되어 있다.

 

 

문제1.c:\\data500 폴더를 만들고 emp.csv를 폴더에 넣으시오.
emp.csv
0.00MB

문제2. pandas를 이용하지 않고 emp.csv에서 모든 컬럼을 출력하시오. 
import   csv

file_path = 'c:\\data500\\emp.csv'

with  open(file_path, mode='r', encoding='utf-8') as  file:
    csv_reader = csv.reader(file)
    header = next(csv_reader)   # 맨위줄의 컬럼명 가져오기
    print('Columns:', header )    # 컬럼명 출력
    for   row  in  csv_reader:
        print(row)​

문제3. 아래의 SQL을 파이썬으로 수행하시오.
1) SQL
select ename,sal
	from emp
    where ename ='SCOTT';

2) python
import   csv

file_path = 'c:\\data500\\emp.csv'

with  open(file_path, mode='r', encoding='utf-8') as  file:
    csv_reader = csv.reader(file)
    header = next(csv_reader)
    #print('Columns:', header )
    for   row  in  csv_reader:
        if row[1]=='SCOTT':
            print(row[1], row[5])

 


문제4. emp.csv 를 판다스 데이터 프레임으로 구성하시오

import pandas as pd

emp = pd.read_csv( 'c:\\data500\\emp.csv' )
emp

문제 5. ename 이 scott 인 사원의 이름과 월급을 출력하시오. 
문법: 데이터 프레임명[[컬럼명 리스트]][검색조건]

emp[['ename','sal']][emp['ename']=='SCOTT']


문제 6. 아래의 sql을 판다스로 출력하시오.

1) SQL
select ename, sal
	from emp;
    
2) python
emp[['ename','sal']]

 

-> sql을 알면 sqldf 모듈로 파이썬에서 데이터 검색해도 되는데 굳이 판다스를 사용하는 이유는 파이썬의 sqldf가 모든 sql을 지원하지는 않음 


 

○ 1 유형_1. 특정 검색조건에 해당하는 데이터 찾기

문법: 데이터 프레임명[['컬럼명1', '컬럼명2']][검색조건]

※ 비교연산자  
 오라클 vs  파이썬
>   >  
 >=    >=  
<    <   
<=    <=   
 !=    !=  
= == 

 

 

※  판다스 데이터 프레임 (dataframe) 과 판다스 시리즈(series) 의 차이?

      오라클의 테이블과  컬럼이라고 보면 됩니다. 

컬럼(시리즈) 에는 데이터를 잘 검색할 수 있게 도와주는 함수들의 여러개 있습니다.
그중에 apply 라는 함수가 있습니다.  apply 함수는 이름 그대로 적용하겠다는 뜻입니다.

 

예제1. 월급이 3000인 사원들의 이름과 월급을 출력하시오.
emp[ ['ename', 'sal'] ] [ emp['sal'] == 3000 ]​

예제2. 월급이 1200인 사원들의 이름과 월급과 직업을 출력하시오.
emp[ ['ename', 'job','sal'] ] [ emp['sal'] >= 1200 ]​



○ 1 유형_2. 빅분기 시험에 자주 나오는 기타 비교 연산자 4가지

 오라클 vs  파이썬
between... and emp['sal'].between(1000,3000)
in emp['job'].isin([10,20])
is null   emp['comm'].isnull()
like emp['ename'].apply(lamba 함수)
예제1. 월급이 1000에서 3000사이인 사원들의 이름과 월급을 출력하시오.
emp[['ename','sal']][emp['sal'].between(1000,3000)]​

예제 2. 월급이 1000에서 3000사이가 아닌 사원들의 이름과 월급을 출력하시오.
emp[['ename','sal']][~emp['sal'].between(1000,3000)]​

 

설명: 검색조건 앞에 '~' 는 not을 의미함

예제 3. 직업이 salesman, analyst인 사원들의 이름, 직업을 출력하시오. 
emp[['ename','job']][emp['job'].isin(['SALESMAN', 'ANALYST'])]​


예제 4. 직업이  salesman, analyst 아닌 사원들의 이름, 직업을 출력하시오. 

emp[['ename','job']][~emp['job'].isin(['SALESMAN', 'ANALYST'])]​

예제 5. comm이 null 이 아닌 사원들의 이름과 comm을 출력하시오. 
emp[['ename','comm']][~emp['comm'].isnull()]​

-> 결측치 확인 할때 .isnull 을 많이 활용함


예제 6. emp 데이터 프레임에 결측치가 있는 컬럼을 확인하시오.
emp.isnull().sum()​

 

-> 정제가 필요한 결측값은 주로 0으로 많이 치환함

예제7. tatanic2.sv에 결측치가 가장 많은 컬럼이 뭔지 출력하시오
import pandas as pd

tat = pd.read_csv( 'c:\\data\\tatanic2.csv' )
tat.isnull().sum().idxmax()

예제 8. 이름의 첫번째 철자가 A 인 사원들의 이름과 월급을 출력하시오 
1) SQL
select  ename, sal
           from  emp
           where  substr(ename, 1, 1 )='A';​
           
2) python
emp[['ename', 'sal']] [ emp['ename'].apply(lambda  x : x[0]=='A' )  ]​


예제 9. 아래의 SQL을 판다스로 구현하시오 !

1) SQL
select  ename, sal
          from  emp
          where  ename  like  '_M%';​

2) python
emp[['ename', 'sal']] [ emp['ename'].apply(lambda  x : x[1]=='M' )  ]​

예제 10. 아래의 SQL을 판다스로 구현하시오 
1) SQL
select ename, sal
	from emp
    where ename like '%T';
    
2) python
emp[['ename', 'sal']] [ emp['ename'].apply(lambda  x : x[-1]=='T' )  ]​



예제 11. 아래의 SQL을 판다스로 구현하시오 
1) SQL
select  ename, sal
          from  emp
          where   ename  like  '%T';
          
2) python
tat[['survived','class']][tat['class'].apply(lambda x : x[-1] == 't') ]​

 


○ 1 유형_3. 데이터 정렬하기

예제1. 이름, 월급을 출력하는데 월급이 높은 사원부터 출력하시오.
1) SQL
select ename, sal
	from emp
    order by sal desc;
    
2) python
emp[['ename','sal']].sort_values(by='sal', ascending = False)​

 

문제 1. 아래의 SQL을 pandas로 구현하시오.
1)SQL
select ename, sal, job
	from emp
    where job ='SALESMAN'
    order by sal desc;
    
2) python
result= emp[['ename','sal','job']][emp['job'] =='SALESMAN']
result.sort_values(by='sal', ascending = False)

 


문제 2.  타이타닉 데이터에서 fare가 높은 승객부터 모든컬럼을 출력하시오.

tat[:].sort_values(by='fare', ascending = False)

 


○ 1 유형_4.  날짜형 데이터 

 

기본적으로 엑셀이나 csv 파일을 판다스 데이터 프레임으로 구성하게 되면 날짜 형식이 object 로 구성됩니다.  

그런데 날짜를 검색할때는 데이터가 문자형이 아니라 날짜형이어야 정확하게 데이터를 검색할 수 있습니다. 

 

예제1. emp 테이블 프레임의 구조를 확인합니다.
emp.info()​
예제2. emp 데이터 프레임의 hiredate를 날짜형으로 변환하여 구성하시오.
import pandas as pd

emp['hiredate'] = pd.to_datetime(emp['hiredate'])
emp.info()​


문제1. 아래의 sql을 판다스로 구현하시오.
1) SQL
select ename, hiredate
	from emp
    where hiredate ='81-11-17';
    
    
2) python
emp[['ename','hiredate']][emp['hiredate'] =='1981-11-17']​


문제2.  아래의 sql을 판다스로 구현하시오.

1) SQL
select ename, hiredate
	from emp
    where hiredate between '81-01-01' and '81-07-20';
    
2) python
emp[['ename','hiredate']][emp['hiredate'].between('1981-01-01','1981-07-20')]


문제3.  아래의 sql을 판다스로 구현하시오.

1) SQL
select ename, job, hiredate
	from emp
    where job =='SALESMAN'
    ordr by hiredate desc;

2) python
result = emp[['ename', 'job','hiredate']][emp['job'] == 'SALESMAN']
result.sort_values(by='hiredate' ,ascending =False)

○ 1 유형_5. 중복 값 제거하기

예제1. 부서번호를 출력하는데 중복값을 제거하시오.
1) SQL
select distinct deptno
	from emp;
    
2) python
print(emp['deptno'].unique())
문제 1. 아래의 sql을 판다스로 구현하시오.
1) SQL
select distinct deptno
	from emp
    where job = 'SALESMAN';

2) python
result = emp[['deptno', 'job']][emp['job'] == 'SALESMAN']
print(result['deptno'].unique())


※  print(type(emp[['deptno']] ))    # <class 'pandas.core.frame.DataFrame'>
    print(type(emp['deptno'] ))      # <class 'pandas.core.series.Series'>
  
 판다스의 대부분의 함수들은 데이터 프레임 보다는 시리즈에서 쓸수 있습니다.

 


○ 1 유형_6.  문자형 데이터 

※ 문자 함수  
 오라클 vs

 파이썬
upper   문자열.upper()
 lower 문자열.lower()
initcap 문자열.capitalize()
substr 문자열[시작숫자:끝숫자] (slice)
 length len( 문자열)
ltrim 문자열.lstrip()
rtrim 문자열.rstrip()
replace 문자열.replace()
instr 문자열.find() 

 

※ 판다스의 시리즈에 문자함수를 쓰려면 .str 을 쓰면 됨

 

예제1. 이름이 scott인 사원의 이름과 월급을 출력하는데 scott은 소문자로 검색되게 하시오.
emp[['ename','sal']][emp.ename.str.lower()=='scott']​

 

문제1. 직업이 salesman인 사원들의 이름과 직업을 출력하시오(데이터가 소문자인지 대문자인지 모름) 
emp[['ename','job']][emp.job.str.lower()=='salesman']​


문제2. 사이킷런에 내장되어있는 타이타닉호 승객 데이터를 가져오시오.

from sklearn.datasets import fetch_openml

titanic = fetch_openml('titanic', version =1 , as_frame =True)

df = titanic.frame
df.head()​
대소문자가 섞여 있음



문제 2.1. df 데이터 프레임에서 cabin 이 b5 인 승객들의 승객이름을 cabin 을 출력합니다.

df[['name','cabin']][df['cabin'].str.lower() =='b5']​

문제 3. 아래의 sql을 pandas로 출력하시오.
1) SQL
select lower(ename), lower(job)
	from emp;

2) python 

2-1) 데이터 프레임 안건들이기
pd.concat([emp.ename.str.lower(), emp.job.str.lower()], axis =1)
※ 판다스의 concat([시리즈1, 시리즈2], axis = 1) # axis = 1은 양옆으로 붙임/ axis = 0은 위/아래로 붙임

2-2) 데이터 프레임 변경
emp['ename'] =emp['ename'].str.lower()
emp['job'] =emp['job'].str.lower()
emp[['ename','job']]
※ 변경한걸 다시 되돌리고 싶으면 re-load 해야됨


문제 4. 아래의 sql을 pandas로 출력하시오.

1) SQL
select upper(ename), initcap(job)
	from emp;
    
2) python
pd.concat([emp.ename.str.upper(), emp.job.str.capitalize()], axis = 1)


문제 5. 아래의 sql을 pandas로 출력하시오.

1) SQL
select substr(ename,1,2)
	from emp;

2) python
emp.ename.str.slice(start = 0, stop =2) # 0부터 1까지 나오게해라


문제 6. 아래의 sql을 pandas로 출력하시오.

1) SQL
select ename, length(ename)
	from emp;
    
2) python

2-1) 데이터 프레임 변경 x
pd.concat([emp.ename, emp.ename.str.len()],axis=1)

2-2) 데이터 프레임 변경 o
emp['ename_len']= emp.ename.str.len()
emp[['ename','ename_len']]


문제 7. 타이타닉 승객 이름을 출력하는데 승객 이름이 가장 긴 승객 순으로 정렬해서 출력하고 위의 5명만출력하시오.

1) SQL
select ename,length(ename) 
	from df
    order by length(ename) desc fetch rows only 5 rows only;
    
2) pandas
2-1) 데이터 프레임 변경 x
result=pd.concat([df.name, df.name.str.len()],axis=1)
result.head(5)

2-2) 데이터 프레임 변경o
df['name_len'] = df.name.str.len()
a = df[['name', 'name_len']].sort_values(by='name_len', ascending=False).head(5)
print(a)

문제 8. 아래의 sql을 pandas로 출력하시오.
1) SQL
select name, instr(ename,',')
	from df;
    
2) python
2-1) 데이터 프레임 변경x
pd.concat([df.name, df.name.str.find(',')], axis =1)

2-2) 데이터 프레임 변경o
df['name_comma']= df.name.str.find(',')
df[['name','name_comma']]


문제 9. 위의 코드에서 '.' 위치도 찾으시오.
1) 데이터 프레임 변화가 없을경우

pd.concat([df.name, df.name.str.find(','),df.name.str.find('.')], axis =1)

 

-> 컬럼명이 모두 같음

2) 데이터 프레임 변경이 있을 경우

df['name_comma']= df.name.str.find(',')
df['name_dot']= df.name.str.find('.')
df[['name','name_comma','name_dot']]
-> 컬럼명이 모두 바뀌어 구분하기 좋음

문제 10. df 데이터에서 승객 이름, 승객의 호칭을 출력하시오.

1) df.apply 사용
# 쉼표와 점의 위치 추출
df['comma_pos'] = df['name'].str.find(',')
df['dot_pos'] = df['name'].str.find('.')


# 쉼표와 점이 모두 존재하는지 확인
df['Title'] = df.apply(
    lambda row: row['name'][row['comma_pos'] + 2:row['dot_pos']].strip(),
    axis=1
)


# 결과 출력
df[['Title', 'name']]

2) 'str.extract' 사용
# 쉼표와 점의 위치 추출
df['comma_pos'] = df['name'].str.find(',')
df['dot_pos'] = df['name'].str.find('.')


# 호칭 추출
df['Title'] = df['name'].str.extract(r',\s*(.*?)\.')


# 결과 출력
df[['Title', 'name']]



문제 11. 아래의 sql을 pandas로 출력하시오.
1) SQL
select ename, replace(sal, 0, *)
	from emp;

2) python 
emp['sal2'] = emp['sal'].astype(str)  # sal 을 문자형으로 변환하여 sal2 를 구성한다. 
emp['sal_replace'] = emp.sal2.str.replace('0','*')
emp[['ename', 'sal_replace']]​


문제 12. 위의 경우는 *가 0이라는 것을 알면 보안이 취약해 지므로 월급을 출력할 때 0~3까지의 숫자를 *로 출력하시오

1) SQL
select ename, regexp_replace(sal, '[0-3]', '*')
	from emp;
    
2) python
import re
emp['sal_star'] = emp.sal.apply(lambda x: re.sub('[0-3]','*',str(x)))
emp[['ename', 'sal_star']]
문제13. 개인정보 변경 실습
1. 타이타닉 데이터에서 이름,나이를 출력하시오.
df[['name','age']]​

2. 이름, 나이(예: 20대) 로 출력하시오.

df['age2'] = df['age'].astype(str)
df['age3'] = df['age2'].str.slice(start=0,stop=1) + '0대'
df[['name', 'age3']]​

문제 14. 아래의 sql을 pandas로 출력하시오.
1) SQL
select ename, sal
	from emp
    where trim(ename) ='SCOTT '; #scott 양쪽에 공백이 있으면 잘라내라

2) python
emp[['ename','sal']][emp.ename.str.strip() =='SCOTT']

- 문자열 (lstrip): 문자열에서 존재하는 왼쪽 공백제거 / 문자열 (rstrip): 문자열에서 존재하는 오른쪽 공백제거

- 문자열 (strip): 문자열에서 존재하는 양쪽 공백제거

○ 1 유형_7. 그룹함수 다루기

※ 그룹함수
 오라클 vs

 파이썬
max   emp['sal'].max()
min emp['sal'].min()
sum emp['sal'].sum()
avg emp['sal'].mean()
count emp['sal'].count()
ltrim emp['sal'].

 

문제1. 아래의 sql을 pandas로 구현하시오
1) SQL
select max(sal)
	from emp;
    
2) python
emp['sal'].max()​


문제2. 아래의 sql을 pandas로 구현하시오

 

1) SQL
select max(sal)
	from emp
    where deptno =20;
    
2) python
emp[['sal']][emp.deptno == 20].max()​


문제3. 타이타닉 데이터에서 pclass 가 1인 승객들의 평균나이를 출력하시오.

df[['age']][df.pclass ==1].mean().round()


문제4. 아래의 sql을 pandas로 구현하시오

1) SQL
select job, max(sal)
	from emp
    group by job;
    
2) pandas
emp.groupby('job')['sal'].max().reset_index()​

->  groupby 와 reset_index() 는 서로 짝꿍입니다. groupby 만 사용하면 결과가 Series 로 나오고 reset_index() 를 뒤에 붙여줘야 dataFrame 으로 출력됩니다. 


+) 컬럼명 바꾸기

result = emp.groupby('job')['sal'].max().reset_index()
result.columns = ['job','sumsal']
result


문제 5. 아래의 sql을 pandas로 구현하시오

1) SQL
select deptno, sum(sal)
	from emp
    group by deptno;
    
2) python
result = emp.groupby('deptno')['sal'].sum().reset_index()
result.columns = ['deptno','sumsal']
result

 


문제 6. 위의 결과를 원형그래프로 시각화하시오.
import pandas as pd
import matplotlib.pyplot as plt

# 그룹화하여 부서별 총 급여 계산
result = emp.groupby('deptno')['sal'].sum().reset_index()
result.columns = ['deptno', 'sumsal']

# 원형 그래프 그리기
plt.figure(figsize=(8, 6))
colors = ['pink', 'skyblue','coral']
plt.pie(result['sumsal'], labels=result['deptno'], autopct='%1.1f%%', startangle=140, explode=[0.05,0.05,0.05],colors=colors)  
# startangle 그래프의 시작 각도를 설정하는 매개변수
# explode 그래프별 공간 생성
plt.title('Department Salary Distribution')
plt.show()
★ 마지막문제.
1) SQL
select job, sum(sal)
	from emp
    group by job;

2) python
import pandas as pd
import matplotlib.pyplot as plt

# 그룹화하여 부서별 총 급여 계산
result = emp.groupby('job')['sal'].sum().reset_index()
result.columns = ['job', 'sumsal']

# 원형 그래프 그리기
plt.figure(figsize=(8, 6))
colors = ['#80C0F6', '#6CCF99','#B580F6', '#F5A15B', '#CF8BB0']
plt.pie(result['sumsal'], labels=result['job'], autopct='%1.1f%%', startangle=140,explode=[0.02,0.02,0.02,0.02,0.02], colors=colors)  
# startangle 그래프의 시작 각도를 설정하는 매개변수
# explode 그래프별 공간 생성
plt.title('Job Salary Distribution')
plt.show()