■ with 문
파일 객체를 자동으로 닫아주는 문

with open('C:\\data\\test.txt', 'w') as file:
    for i in range(1,11):
        txt = '{} 꿈을 오랫동안 그리는 사람은 마침내 그 꿈을 닮아간다.\n'.format(i)
        file.write(txt)
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

 




★ SQL Developer에서 CSV 추출

SELECT * FROM hr.employees;
>>  날짜형식 : 03/06/17 -> 19C, 20C 확인불가

select * from nls_session_parameters;
>> NLS_DATE_FORMAT RR/MM/DD

alter session set nls_date_format = 'yyyy-mm-dd';   # session 사용중에만 형식변경
select * from nls_session_parameters;
>> NLS_DATE_FORMAT yyyy-mm-dd
도구 - 데이터베이스 익스포트 - 익스포트 마법사

접속 hr
데이터만
행 터미네이터 : 기본값 -> 한 행씩 
csv형식 -> , 로 구분
문자열 " " 둘러싸기 >> 이거 안하면 데이터 모든 공백에 , 들어감

 




■ csv
import csv

file = open("C:\\data\\emp.csv",'r')
emp_csv = csv.reader(file)

emp_csv             # <_csv.reader at 0x1f5c58b2b60>

next(emp_csv)       # 한행씩 메모리의 내용을 보자. List

for i in emp_csv:
    print(i)        # List
    
file.close()
with open("C:\\data\\emp.csv",'r') as file:
    emp_csv = csv.reader(file)

    for i in emp_csv:
        print(i)        # List

 

with open("C:\\data\\emp.csv",'r') as file:
    emp_csv = csv.reader(file)
    next(emp_csv)               # 실행 후 for문하면 칼럼명 안나옴
    for i in emp_csv:
        print(i[0],i[2],i[7],i[8],i[10])        # 칼럼추출
with open("C:\\data\\emp.csv",'r') as file:
    emp_csv = csv.reader(file)
    next(emp_csv)               # next실행으로 1행 읽은 후 FOR문하면 칼럼명 안나옴
    for i in emp_csv:
        print(i[0],i[2],int(i[7])*12,i[8],i[10])        # i[7] : salary
    
>> csv는 문자형, 계산필요 시 int 형변환하기

 

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])    
        # i[8] : comm // 결측치는 공백으로 표시된다.
||
def ifnull(arg1,arg2):                  # ifnull 공백이면 0, 아니면 값 리턴
    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))      # ifnull() 사용자함수

 




■ lambda 람다

- 이름이 없는 한줄짜리 함수
- 가독성

(lambda 형식매개변수 : 리턴값)(위치지정방식)

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)

 

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))
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)))

 

import datetime
# 입사요일
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],'월화수목금토일'[datetime.datetime.strptime(i[5],'%Y-%m-%d').weekday()]+'요일')


'월화수목금토일'[datetime.datetime.strptime('2023-11-17','%Y-%m-%d').weekday()]+'요일'
'월화수목금토일'[datetime.datetime.strptime(i[5],'%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],(datetime.datetime.now() - datetime.datetime.strptime(i[5],'%Y-%m-%d')).days)

 




■ pandas 판다스
- 데이터분석기능을 제공하는 라이브러리(모듈)
- 1차원 배열 : Series
- 2차원 배열 : DataFrame

from pandas import Series, DataFrame
import pandas as pd


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

s = Series([1,2,3,4,5])
s
0    1
1    2
2    3
3    4
4    5
dtype: int64
type(s) pandas.core.series.Series
s + 100 0    101
1    102
2    103
3    104
4    105
dtype: int64
s.astype 0    1
1    2
2    3
3    4
4    5
dtype: int64>

 

s = Series(['1',2,3,4,5])    # 문자포함
s
0    1
1    2
2    3
3    4
4    5
dtype: object       # 문자
s + 100 오류 = 문자 + 숫자
# 형식변환, 미리보기
s.astype('int')
0    1
1    2
2    3
3    4
4    5
dtype: int32        # int32 : 기본값

 

# Series 인덱스 확인
s.index
RangeIndex(start=0, stop=5, step=1)
# Series 값 확인
s.values
array([1, 2, 3, 4, 5], dtype=int64)     # 배열
# 인덱스 수정
s.index = ['a','b','c','d','e']
기존
0    1
1    2
2    3
3    4
4    5
dtype: int64
변경
a    1
b    2
c    3
d    4
e    5
dtype: int64
s.index Index(['a', 'b', 'c', 'd', 'e'], dtype='object')


# Series 인덱싱
s['a']          # Series['인덱스 이름']
s[['a','e']]    # 여러개
a    1
e    5
dtype: int64

s[0]        # Series[인덱스 위치]
s[1]
s[-1]

# Series 슬라이싱
s[0:3]      # Series[시작인덱스위치 : 종료인덱스위치 -1]
s['a':'d']  # Series[시작인덱스이름 : 종료인덱스이름]
 
# 조건
s >= 3
s[s >= 3]
c    3
d    4
e    5
dtype: int64

# Series 인덱스 이름 체크
'a' in s    # True
'z' in s    # False

# Sereis 값 수정
s['a'] = 100
s
a    100
b      2
c      3
d      4
e      5
dtype: int64

# Sereis 새로운 값 추가
s['f'] = 6
s
a    100
b      2
c      3
d      4
e      5
f      6
dtype: int64

# Series 빈문자열 추가
s['f'] = ''
s
a    100
b      2
c      3
d      4
e      5
f       
dtype: object       # 문자타입으로 변경 됨

# Series 인덱스, 값 삭제
del s['f']
s

# Series 삭제
del s



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

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

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

set = {1,2,3,4,5}
Series(set)         # set : 인덱스가 없어 사용 불가.

Series(list(set))

dic = {'a':10,'b':20,'c':30}
ix = {'a','b','f'}
type(ix)            # set 타입

Series(dic, index=ix)   # 인덱스를 기준으로 가져오자
b    20.0
a    10.0
f     NaN
dtype: float64

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

dic = {'a':10,'b':20,'c':30}
ix = ['a','b','f','a']      # 인덱스를 list로하면 중복성이 있다.
Series(dic, index=ix)
a    10.0
b    20.0
f     NaN
a    10.0
dtype: float64

dic = {'a':10,'b':20,'c':30}
ix = {'a','b','f','a'}
s = Series(dic, index=ix)
s
b    20.0
a    10.0
f     NaN
dtype: float64



# NaN 체크하는 방법
pd.isnull(s)
b    False
a    False
f     True
dtype: bool

s[pd.isnull(s)]
f   NaN
dtype: float64

# NaN 아닌 체크하는 방법
pd.notnull(s)
b     True
a     True
f    False
dtype: bool

s[pd.notnull(s)]
b    20.0
a    10.0
dtype: float64



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

city = {'서울','경기','제주','대전'}
y = Series(x, index=city)
y
경기    700.0
제주    100.0
서울    500.0
대전      NaN
dtype: float64



# 서로 다른 Series에 인덱스를 기준으로 연산 작업
x + y
경기    1400.0
대전       NaN
부산       NaN
서울    1000.0
제주     200.0
dtype: float64

x - y
경기    0.0
대전    NaN
부산    NaN
서울    0.0
제주    0.0
dtype: float64


x.name = '인구수'
x
서울    500
부산    300
경기    700
제주    100
Name: 인구수, dtype: int64

x.name = ''
x
서울    500
부산    300
경기    700
제주    100
Name: , dtype: int64

x.name = None
x
서울    500
부산    300
경기    700
제주    100
dtype: int64


x.index.name = '지역명'
x
지역명
서울    500
부산    300
경기    700
제주    100
dtype: int64


x.index.name = None
x
서울    500
부산    300
경기    700
제주    100
dtype: int64





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

df = DataFrame([ [1,2,3], [4,5,6], [7,8,9] ])
df
   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9
type(df)  pandas.core.frame.DataFrame

 

data = {'도시':['서울','부산','강원','인천'],
        '인구수':[500,400,200,300]}

df = DataFrame(data)
df
   도시  인구수
0  서울  500
1  부산  400
2  강원  200
3  인천  300

df.info()       # DataFrame 정보 확인

df.columns      # 컬럼 정보 : Index(['도시', '인구수'], dtype='object')
df.index        # 인덱스 정보 : RangeIndex(start=0, stop=4, step=1)
df.values

df.columns[0]
df.columns[0] = '지역'        # 특정 인덱스만 수정 불가

df.columns = ['지역','가구수']   # 컬럼 수정
df
   지역  가구수
0  서울  500
1  부산  400
2  강원  200
3  인천  300


# 열 확인
df['지역']        # Series
df.지역

df.['가구수'] * 100
df


# 인덱스 수정
df.index = ['one','two','three','four']
df


# 행 선택
df.iloc[인덱스 위치]

df.iloc[0]
df.iloc[1]

df.iloc['one']      # 오류 : iloc는 인덱스 위치 정보만 사용가능하다.


df.loc[인덱스 이름]
df.loc['one']

df.loc[0]           # 오류


# 새로운 컬럼 추가
df['부채'] = [1000,300,100,50]
df
       지역  가구수    부채
one    서울  500  1000
two    부산  400   300
three  강원  200   100
four   인천  300    50


# 열 삭제
del df['부채']
df


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

df = DataFrame(data)
df
         서울   부산
2001  200.0   50
2002  300.0  200
2000    NaN  100


df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 3 entries, 2001 to 2000
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   서울      2 non-null      float64        # 총 3행 중 1개 결측치
 1   부산      3 non-null      int64  
dtypes: float64(1), int64(1)
memory usage: 72.0 bytes


df.dtypes           # 전체 컬럼의 타입
서울    float64
부산      int64
dtype: object


df['서울'].dtype      # 특정 컬럼의 타입 확인
df['서울'].dtypes 


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



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


# reindex : 새로운 인덱스에 맞도록 객체를 생성하는 기능, 미리보기
obj.reindex(['a','b','c','d'])
a    20
b    40
c    10
d    30
dtype: int64


obj.reindex(['a','b','c','d','e'])
a    20.0
b    40.0
c    10.0
d    30.0
e     NaN
dtype: float64


obj.reindex(['a','b','c'])
a    20
b    40
c    10
dtype: int64


# fill_value=0 : 결측값(NaN) 대신 0으로 채우기
obj.reindex(['a','b','c','d','e'], fill_value=0)
a    20
b    40
c    10
d    30
e     0
dtype: int64





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


df.reindex(['b','c','a'])
   x  y  z
b  4  5  6
c  7  8  9
a  1  2  3


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


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


# method = 'ffill' 또는 'pad' 사용하여 NaN 대신 앞의 행의 값으로 채운다
df3 = df.reindex(['a','b','c','d'], method='ffill')
df3

df4 = df.reindex(['a','b','c','d'], method='pad')
df4
   x  y  z
a  1  2  3
b  4  5  6
c  7  8  9
d  7  8  9





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

# method = 'ffill' 또는 'pad' 사용하여 NaN 대신 앞의 행의 값으로 채운다
df5 = df.reindex(['a','b','c','d'], method='bfill')
df5

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

   x  y  z
a  1  2  3
b  4  5  6
c  4  5  6
d  7  8  9





obj = Series(['SQL','R','PYTHON'],index=[0,2,4])
obj.reindex([0,1,2,3,4,5])
0       SQL
1       NaN
2         R
3       NaN
4    PYTHON
5       NaN
dtype: object

obj.reindex([0,1,2,3,4,5], fill_value='ORACLE')
0       SQL
1    ORACLE
2         R
3    ORACLE
4    PYTHON
5    ORACLE
dtype: object

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



# 데이터프레임 행 삭제, 미리보기
df.drop('a')

df.drop('a', axis=0)    # 기본값 = 0, 행삭제 (미리보기)

df.drop(['a','c'], axis=0)  # 


df.drop('x', axis=1)    # axis=1 : 열삭제(미리보기)
df.drop(['x','z'], axis=1)

del df['x']             # 즉시 영구삭제

df



emp = pd.read_csv("C:\\data\\employees.csv")
emp

emp.info()

emp.shape       # (107, 11) : (행,열)의 수
emp.head()      # 위에서 행제한, 기본값 : 5
emp.tail()      # 뒤에서 행제한, 기본값 : 5


# 출력할 수 있는 칼럼의 수 정보 확인
pd.options.display.max_columns      # 0 : 기본값
pd.get_option('display.max_columns')


# 출력할 수 있는 칼럼의 수 설정
pd.set_option('display.max_columns',11)     # 11개 칼럼 보이기
pd.get_option('display.max_columns')        # 11
emp
emp.head()

# 출력할 수 있는 컬럼의 수를 기본값으로 설정
pd.reset_option('display.max_columns')      # 초기화
pd.get_option('display.max_columns')
emp.head()



# 출력할 수 있는 행의 수 정보 확인
pd.options.display.max_rows             # 60 : 기본값
pd.get_option('display.max_rows')

# 출력할 수 있는 행의 수 설정
pd.set_option('display.max_rows',3)   # 화면에 보이는 행 제한
pd.get_option('display.max_rows')
emp
emp.head()

# 출력할 수 있는 행의 수를 기본값으로 설정
pd.reset_option('display.max_rows')      # 초기화
pd.get_option('display.max_rows')
emp.head()



select * from employees where employee_id = 100;
emp[emp['EMPLOYEE_ID'] == 100]
emp.loc[emp['EMPLOYEE_ID'] == 100,]


# [행추출조건][열이름] -> 순서무관
emp[emp['EMPLOYEE_ID'] == 100]['LAST_NAME']
||
# [행추출 조건, 열추출 조건]
emp.loc[emp['EMPLOYEE_ID'] == 100,'LAST_NAME']


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



SELECT last_name, salary
FROM emp
WHERE job_id = 'ST_CLERK';

emp[emp['JOB_ID'] == 'ST_CLERK'][['LAST_NAME','SALARY']]
emp.loc[emp['JOB_ID'] == 'ST_CLERK',['LAST_NAME','SALARY']]



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']]
emp[['LAST_NAME','SALARY','HIRE_DATE']][emp['SALARY'] >= 10000]






■ 정렬

obj = Series([2,7,2,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()
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)


# 특정 열(칼럼)을 기준으로 오름차순
select a,b,c,d
from df
order by a;

df.sort_values(by='a', ascending=True)


# 특정열(칼럼) 기준으로 내림차순
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)



select last_name, salary, department_id
from emp
where salary >= 10000
order by department_id asc;

x = emp.loc[emp['SALARY'] >= 10000,['LAST_NAME','SALARY','DEPARTMENT_ID']]
result = x.sort_values(by='DEPARTMENT_ID', ascending=True, axis=0)

# index 재설정, 기존인덱스는 컬럼으로 추가된다.
result = result.reset_index()       
result

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



select last_name, salary, department_id
from emp
where salary >= 10000
order by department_id asc, salary asc;

x = emp.loc[emp['SALARY'] >= 10000,['LAST_NAME','SALARY','DEPARTMENT_ID']]
result = x.sort_values(by=['DEPARTMENT_ID','SALARY'], ascending=True, axis=0)
result



select last_name, salary, department_id
from emp
where salary >= 10000
order by department_id asc, salary desc;

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