Language/Python

231117 Python_with문, csv, lambda 함수, pandas, Series, DataFrame, 정렬

잇꼬 2023. 11. 20. 19:35
728x90
반응형
SMALL

# plsql with문 -> line view 보기만
■ with 문 : open + close 
#1 파일 객체를 자동을 닫아주는 문

with open("c:/data/test.txt", "w") as file:
    for i in range(1, 11):
        txt = "{} 꿈을 오랫동안 그리는 사람은 마침내 그 꿈을 닮아간다.\n".format(i)
        file.write(txt)
        # close 하지 않아도 자동으로 close된다.

with open("c:/data/test.txt", "a") as file:
    for i in range(11, 21):
        txt = "{} 꿈을 오랫동안 그리는 사람은 마침내 그 꿈을 닮아간다.\n".format(i)
        file.write(txt)

with open("c:/data/test.txt", "r") as file:
    data = file.readlines()

data


■ csv 

import csv

file = open("c:/data/emp.csv", "r")
file
emp_csv = csv.reader(file)
emp_csv # 메모리에 할당만 되어 있을뿐


# next() : fetch와 같은 결과

next(emp_csv) # 첫 번째 행부터


# file을 읽기 위해서는 open 부터 close 하기

file = open("c:/data/emp.csv", "r")
emp_csv = csv.reader(file)
for i in emp_csv:
    print(i)
file.close()


# with 문으로 변경 

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i)


# 원하는 컬럼만 출력

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], i[2], i[7], i[8], i[10])

 

# salary *12 -> 계산X 문자복제

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], i[2], i[7]*12, i[8], i[10])


# 해결) 형변환

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], i[2], int(i[7])*12, i[8], i[10])

 

# i[8](commission_pct)=null 은 공백으로 확인

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], i[8])


# 해결) i[8](commission_pct)=null 은 공백으로 확인, 공백을 0 으로 표시(if문)

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], 0 if i[8] == '' else i[8])


# 빈문자열이면 0 문자가 있다면 i[8] 출력하는 = 함수 ifnull 생성. 

def ifnull(arg1, arg2):
    if arg1 == '':
        return arg2
    else:
        return arg1

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], ifnull(i[8],0))


■ 람다(lambda) 함수
#1. (lambda 형식매개변수, 형식매개변수:표현식)(인수값, 인수값)
#2. 이름이 없는 한줄짜리 함수
#3. 가독성을 위해서 (읽기 편함)

def f1(x,y):
    return x+y

f1(10, 20)

(lambda x,y:x+y)(10,20)

f2 = lambda x,y:x+y
f2(10,20)


# 람다식 변경

import csv
with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], (lambda x,y:y if x == '' else x)(i[8],0))



# i[7](salary) : int 형변화, i[8] : 소수점, 문자형 -> float 형변환(실수형) + null 값은 0 으로 변환
# int(i[7]) * 12 + float((lambda x,y:y if x == '' else x)(i[8],0))

with open("c:/data/emp.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], int(i[7]) * 12 + float((lambda x,y:y if x == '' else x)(i[8],0)))


# i[5] : 날짜

with open("c:/data/employees.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], i[5])

import datetime

datetime.datetime.strptime('2023-11-17', '%Y-%m-%d')
datetime.datetime.strptime('2023-11-17', '%Y-%m-%d').weekday()
'월화수목금토일'[datetime.datetime.strptime('2023-11-17', '%Y-%m-%d').weekday()]+'요일'

with open("c:/data/employees.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], i[5])


# i[5] : 문자형 -> 날짜 형변화

with open("c:/data/employees.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], '월화수목금토일'[datetime.datetime.strptime(i[5], '%Y-%m-%d').weekday()]+'요일')


# 일수계산

(datetime.datetime.now() - datetime.datetime.strptime('2023-11-17', '%Y-%m-%d')).days



# 근무일수 출력, i[5](hire_date)

with open("c:/data/employees.csv", "r") as file:
    emp_csv = csv.reader(file)
    next(emp_csv)
    for i in emp_csv:
        print(i[0], (datetime.datetime.now() - datetime.datetime.strptime(i[5], '%Y-%m-%d')).days)


■ pandas
#1. 데이터 분석 기능을 제공하는 라이브러리(모듈)
#2. 1차원 배열 : Series
#3. 2차원 배열 : DataFrame(테이블구조)

★ Series
#1. 1차원 배열
#2. 인덱스(색인) 배열의 데이터에 연관된 이름을 가지고 있ㅎ다. 
#3. 단일 데이터 타입만 가능하다.

from pandas import Series, DataFrame
import pandas as pd # 별칭가능

lst = [1,2,3,4,5]
type(lst)
lst[0] + 100
lst[1] + 100
lst[2] + 100
lst[3] + 100
lst[4] + 100

[i + 100 for i in lst]

s = Series([1,2,3,4,5])
s
s + 100
type(s)
s.astype # 타입, 데이터 // int 값, 64비트

s = Series(['1',2,3,4,5])
s # 문자형=object
s + 100 # 오류발생 = 숫자+문자


# 형변환(자료형 변경)

s.astype('int') # 기본값 = int, 32비트 , 미리보기+적용X
s.astype('int64') 
s
s = s.astype('int64') 
s
s + 100


# index 확인 : start=0, stop=5, step=1

s.index # Series 인덱스 확인
s.values # Series 값 확인
s.index = ['a', 'b', 'c', 'd', 'e'] # 인덱스 수정
s.index


# Series 연산작업

s + 100
s - 100
s * 2
s / 2
s // 2
s % 2
s ** 2


# Series 인덱싱

s['a'] # Series [인덱스이름]
s['e']
s[['a','e']] # list 모습으로 출력


# Series [인덱스위치]

s[0] 
s[1]
s[4]
s[-1]
s[-2]
s[-3]


# Series 슬라이싱

s[0:3] # Series[시작인덱스위치:종료인덱스위치-1]
s['a':'d'] # Series[시작인덱스이름:종료인덱스이름]


# 조건 

s >= 3 # bool 형식
s[s >= 3]


# Series 인덱스 이름 체크

'a' in s
'z' in s


# Series 값 수정

s ['a']
s ['a'] = 100
s


# Series 새로운 값 추가 

s['f'] = 6
s


# Series 빈문자열 수정

s['f'] =''
s


# Series 인덱스, 값 삭제

del s['f']
s


# 타입 변환

s.astype('int64')
s = s.astype('int64')
s


# Series 삭제

del s


# Series 생성

lst = [10, 20, 30]
Series(lst)

tuple1 = (10, 20, 30)
Series(tuple1)

dict = {'a':10, 'b':20, 'c':30}
Series(dict)

set = {1,2,3,4,5}
Series(set) # 인덱스가 없어서 set 불가
Series(list(set)) # 해결) list 로 형변환

dic = {'a':10, 'b':20, 'c':30}
ix = {'a', 'b', 'f'} # set 형, 중복성X
ix
type(ix)
dic

Series(dic)


# index 기준으로 갖고 오기, NaN=null

Series(dic, index=ix)


# NaN(Not a Number) : null, 결측값(치)
# - NaN 값이 있는 경우 : 실수형으로 생성

dic = {'a':10, 'b':20, 'c':30}
ix = ['a', 'b', 'f'] # list 형
Series(dic, index=ix)

dic = {'a':10, 'b':20, 'c':30}
ix = ['a', 'b', 'f', 'a'] # list 형
Series(dic, index=ix) # 인덱스가 중복성이 되어 있다.

dic = {'a':10, 'b':20, 'c':30}
ix = {'a', 'b', 'f', 'a'}
Series(dic, index=ix) # 인덱스가 중복성이 되어 있다.

dic = {'a':10, 'b':20, 'c':30}
ix = {'a', 'b', 'f', 'a'}
Series(dic, index=ix) # 인덱스가 중복성이 되어 있다.
s = Series([1,2,3,4,5])
s


# NaN 체크하는 방법 

pd.isnull(s)
s[pd.isnull(s)]


# NaN 아닌 값

pd.notnull(s)
s[pd.notnull(s)]

x = Series({'서울':500, '부산':300, '경기':700, '제주':100})
x

city = {'서울', '경기', '제주', '대전'}
y = Series(x, index=city)



# 서로 다른 Series 에 인덱스를 기준으로 연산 작업

x + y
x - y
x * y
x / y
x // y
x % y
x ** y # inf : 값이 너무 큰 값, 제주값:지수형식

x
x.name = "인구수" # 속성 지정
x.name =""
x.name = None # 속성을 없을 때
x

x.index.name
x.index.name = "지역명" # 컬러명처럼 확인가능
x.index.name = None
x


★ DataFrame
#1. 2차원 배열(행과 열로 구성) 
#2. 테이블구조
#3. 각컬럼의 서로 다른 종류 데이터 타입을 사용할 수 있다. 

# 2차원 배열 생성 

df = DataFrame([[1,2,3],
               [4,5,6],
               [7,8,9]])
df
type(df)

data = {'도시':['서울', '부산', '강원', '인천'],
        '인구수':[500, 400, 200, 300]}
df = DataFrame(data)
df.info() # 데이터프레임 정보 확인
df.columns # 데이터프레임 컬럼 정보 확인
df.index # 데이터프레임 인덱스 정보 확인
df.values # 데이터프레임 값의 정보 확인

df.columns[0] = '지역' # 특정한 컬럼만 수정할 경우 안된다
df.columns = ['지역', '가구수'] # 컬럼 수정
df
ALTER TABLE 테이블명 RENAME COLUMN 기존컬럼 TO 새로운 컬럼;


# 열 확인

df['지역']
df.지역

df['가구수']*100


# index 수정

df.index
df.index = ['one', 'two', 'three', 'four']
df


# 행 선택

df.iloc[0] # df.iloc[인덱스위치]
df.iloc[1]

df.iloc['one'] # iloc 는 인덱스 위치 정보만 사용, 오류발생

df.loc['one'] # 변수명.loc[인덱스명]
df.loc[0] # loc는 인덱스 이름 정보만 사용, 오류발생


# 새로운 컬럼 추가 

df['부채'] = [1000, 300, 100, 50]
df


# 열 삭제 

del df['부채']
df


# 생성

data = {'서울':{2001:200, 2002:300},
        '부산':{2000:100, 2001:50, 2002:200}}

df = DataFrame(data)
df.index
df.values
df.info()
df.dtypes # 컬럼의 타입
df['서울'].dtypes # 특정컬럼의 타입 확인
df['서울'].dtype
df.dtype # 오류발생, 해결시 전체 타입 확인 dtypes

df.T # 행과 열을 바꾸는 방법
df

obj = Series([10,20,30,40], index=['c', 'a', 'd', 'b'])
obj


# reindex : 새로운 인덱스에 맞도록 객체를 생성하는 기능, 미리보기

obj1 = obj.reindex(['a', 'b', 'c', 'd'])
obj1

obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2

obj3 = obj.reindex(['a', 'b', 'c'])
obj3


# fill_value = 0 , 결측값이 NaN 일 경우 fill_value 로 다른 값으로 변경해주기
# fill_value = 0 : NaN 값 대신 0으로 변경하는 방법

obj4 = obj.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
obj4
                # 열
df = DataFrame([[1,2,3], # 행
               [4,5,6],
               [7,8,9]], # 중첩 
               index=['a', 'b','c'], # index 명
               columns=['x', 'y', 'z']) # column 명
df
df.reindex(['b', 'c', 'a']) # 행도 같이 변경

df1 = df.reindex(['a', 'b', 'c', 'd'])
df1


# fill_value = 0 : reindex 할때 새로운 인덱스 결측값(NaN) 대신 0으로 변경

df2 = df.reindex(['a', 'b', 'c', 'd'], fill_value=0)
df2


# method = 'ffill' or 'pad' NaN 대신 앞의 행의 값으로 채운다.

df3 = df.reindex(['a', 'b', 'c', 'd'], method='ffill')
df3

df4 = df.reindex(['a', 'b', 'c', 'd'], method='pad')
df4

df = DataFrame([[1,2,3],
               [4,5,6],
               [7,8,9]], 
               index=['a', 'c', 'd'], 
               columns=['x', 'y', 'z'])


# method = 'ffill' or 'pad' NaN 대신 앞의 행의 값으로 채운다.

df5 = df.reindex(['a', 'b', 'c', 'd'], method='ffill')
df5

df6 = df.reindex(['a', 'b', 'c', 'd'], method='pad')
df6


# method = 'bfill' or 'backpad' NaN 대신 뒤의 행의 값으로 채운다.

df5 = df.reindex(['a', 'b', 'c', 'd'], method='bfill')
df5

df6 = df.reindex(['a', 'b', 'c', 'd'], method='backfill')
df6

obj= Series(['SQL', 'R', 'PYTHON'], index=[0,2,4])
obj.reindex([0,1,2,3,4,5])
obj.reindex([0,1,2,3,4,5], fill_value='ORACLE')
obj.reindex([0,1,2,3,4,5], method='ffill')
obj.reindex([0,1,2,3,4,5], method='pad')
obj.reindex([0,1,2,3,4,5], method='bfill')
obj.reindex([0,1,2,3,4,5], method='backfill')

del obj[4] # 인덱스, 값을 삭제(즉시수행)
obj

obj.drop(2) # 인덱스, 값을 삭제(미리보기)
obj

obj = obj.drop(2)
obj


# 데이터프레임 행삭제

df.drop('a') # 미리보기
df.drop('a', axis=0) # axis=0 : 행삭제(미리보기)
df.drop(['a', 'c'], axis=0) # list 형태로 행삭제


# 데이터프레임 열삭제

df.drop('x', axis=1) # axis=1 : 열삭제 
df.drop(['y', 'z'], axis=1)
df

del df['x'] # 열 삭제, 즉시 수행
df


# read_csv : csv 파일을 데이터프레임으로 읽어오는 함수

emp = pd.read_csv('c:/data/employees.csv')
emp
emp.info()
emp.shape # (행의 수 , 열의 수)
emp.head()
emp.head(10)
emp.tail() # 뒤에서 5건
emp.tail(7) # 뒤에서 7건
컬럼의 수 
정보 확인
컬럼의 수 
설정
컬럼의 수 
기본값으로 설정
행의 수 
정보 확인
행의 수 
설정
행의 수 
기본값으로 설정
get_option set_option reset_option get_option set_option reset_option


# 출력할 수 있는 컬럼의 수 정보 확인 : get_option

pd.options.display.max_colums
pd.get_option("display.max_columns")


# 출력할 수 있는 컬럼의 수 설정 : set_option

pd.set_option("display.max_columns", 11) # 컬럼의 수 : 11건
pd.get_option("display.max_columns")
emp

emp.head()


# 출력할 수 있는 컬럼의 수를 기본값으로 설정 : reset_option 

pd.reset_option("display.max_columns")
pd.get_option("display.max_columns")
emp.head()


# 출력할 수 있는 행의 수 정보 확인 : get_option

pd.options.display.max_rows
pd.get_option("display.max_rows")


# 출력할 수 있는 행의 수 설정 : set_option

pd.set_option("display.max_rows", 200) 
pd.get_option("display.max_columns")
emp


# 출력할 수 있는 행의 수를 기본값으로 설정 : reset_option 

pd.reset_option("display.max_rows")
pd.get_option("display.max_rows")
emp


# SQL

SELECT * 
FROM employees 
WHERE employee_id = 100;
emp[emp['EMPLOYEE_ID'] == 100]


# [행 추출 조건][열이름] 

emp[emp['EMPLOYEE_ID'] == 100]['LAST_NAME']
emp[emp['EMPLOYEE_ID'] == 100][['LAST_NAME', 'SALARY']] # 중첩


# [행 추출 조건, 열 추출]

emp.loc[emp['EMPLOYEE_ID'] == 100,]
emp.loc[emp['EMPLOYEE_ID'] == 100, 'LAST_NAME']
emp.loc[emp['EMPLOYEE_ID'] == 100, ['LAST_NAME', 'SALARY']]


# 추출방식 위치 영향 X

emp[['LAST_NAME', 'SALARY']][emp['EMPLOYEE_ID'] == 100]


# SQL 

SELECT last_name, salary FROM emp WHERE job_id = 'ST_CLERK';
emp[emp['JOB_ID'] == 'ST_CLERK'][['LAST_NAME', 'SALARY']]
emp[['LAST_NAME', 'SALARY']][emp['JOB_ID'] == 'ST_CLERK']
emp.loc[emp['JOB_ID'] == 'ST_CLERK', ['LAST_NAME', 'SALARY']]
# emp.loc[['LAST_NAME', 'SALARY'], emp['JOB_ID'] == 'ST_CLERK'] 오류발생, index 위치


# SQL 

SELECT LAST_NAME, SALARY, HIRE_DATE FROM emp WHERE SALARY >= 10000;
emp[emp['SALARY'] >= 10000][['LAST_NAME', 'SALARY', 'HIRE_DATE']]
emp.loc[emp['SALARY'] >= 10000, ['LAST_NAME', 'SALARY', 'HIRE_DATE']]


■ 정렬 
# SQL : order by 

obj = Series([2,7,3,8], index=['d', 'a', 'c', 'b'])
obj.reindex(['a', 'b', 'c', 'd'])


# 인덱스를 기준으로 정렬(미리보기)

obj.sort_index()
obj.sort_index(ascending=True) # 오름차순 기본값 
obj.sort_index(ascending=False) # 내림차순


# 값을 기준으로 정렬

obj.sort_values()
obj.sort_values(ascending=True) # 오름차순 기본값
obj.sort_values(ascending=False) # 내림차순

df = DataFrame(data = [[1, 2, 3, 4], 
                       [5, 6, 7, 8]], 
                       index = ['two', 'one'],
                       columns = ['d', 'a', 'c', 'b'])
df
df.reindex(['one', 'two'])


# 인덱스를 기준으로 오름차순 정렬(기본)

df.sort_index()
df.sort_index(ascending=True)
df.sort_index(ascending=True, axis=0) # axis=0 행


# 인덱스를 기준으로 내림차순 정렬

df.sort_index(ascending=False)
df.sort_index(ascending=False, axis=0) # axis=0 행


# 컬럼명 기준으로 오름차순 정렬

df.sort_index(ascending=True, axis=1) # axis=1 열


# 컬럼명 기준으로 내림차순 정렬

df.sort_index(ascending=False, axis=1)


# SQL 

SELECT a, b, c, d FROM df ORDER BY a asc;
df.sort_values(by='a', ascending=True)


# SQL

SELECT a, b, c, d FROM df ORDER BY a desc;
df.sort_values(by='a', ascending=False)



# 특정한 행(인덱스)를 기준으로 정렬

df.sort_values(by='one', ascending=False, axis=1) # 'one' 이라는 행 기준으로 큰 값 으로 정렬


# SQL 

SELECT LAST_NAME, SALARY, DEPARTMENT_ID 
FROM df 
WHERE SALARY >= 10000 
ORDER BY DEPARTMENT_ID asc;
x = emp[emp['SALARY'] >= 10000][['LAST_NAME', 'SALARY', 'DEPARTMENT_ID']]
x = emp.loc[emp['SALARY'] >= 10000, ['LAST_NAME', 'SALARY', 'DEPARTMENT_ID']]
x.sort_values(by='DEPARTMENT_ID', ascending=True, axis=0)
result = x.sort_values(by='DEPARTMENT_ID', ascending=True, axis=0)


# 인덱스 재설정, 기존 인덱스가 컬럼으로 추가(기본값)

result = result.reset_index()
result


# 인덱스 재설정, 기존 인덱스 삭제 : result.reset_index(drop=True)

result = result.reset_index(drop=True)
result


# SQL 

SELECT LAST_NAME, SALARY, DEPARTMENT_ID 
FROM df 
WHERE SALARY >= 10000 
ORDER BY DEPARTMENT_ID asc, SALARY asc;
emp[emp['SALARY'] >= 10000][['LAST_NAME', 'SALARY', 'DEPARTMENT_ID']]
x = emp.loc[emp['SALARY'] >= 10000, ['LAST_NAME', 'SALARY', 'DEPARTMENT_ID']]
result = x.sort_values(by=['DEPARTMENT_ID', 'SALARY'], ascending=True, axis=0)
result



# SQL : 

SELECT LAST_NAME, SALARY, DEPARTMENT_ID 
FROM df 
WHERE SALARY >= 10000 
ORDER BY DEPARTMENT_ID asc, SALARY dssc;

 

x = emp.loc[emp['SALARY'] >= 10000, ['LAST_NAME', 'SALARY', 'DEPARTMENT_ID']]
result = x.sort_values(by=['DEPARTMENT_ID', 'SALARY'], ascending=[True, False], axis=0)
result
728x90
반응형
LIST