Python/라이브러리

파이썬 (python) 라이브러리 - Pandas 판다스

snowman95 2021. 3. 22. 21:26
728x90
반응형

pandas


         - 링크 : pypi.org/project/pandas/

         - 설치방법 : pip install pandas

         - 용도 : 구조화 된 (표 형식, 다차원, 잠재적으로 이기종) 및 시계열 데이터로
                    쉽고 직관적으로 작업 할 수 있도록 설계된 빠르고 유연하며 표현력이 뛰어난 데이터 구조를 제공

 

● padas.DataFrame 생성

1. numpy ndarray (+columns, index)

  0 1 2
0 1 2 3
1 4 5 6
2 7 8 9
import pandas as pd
import numpy as np
df = pd.DataFrame(np.array([[1, 2, 3],   → 이게 하나의 행임. Excel의 가로축 
                            [4, 5, 6], 
                            [7, 8, 9]]))
df
   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9

df = pd.DataFrame(np.array([[1, 2, 3],
                            [4, 5, 6], 
                            [7, 8, 9]]),
                            columns=['A', 'B', 'C'])
df
   A  B  C
0  1  2  3
1  4  5  6
2  7  8  9

df = pd.DataFrame(np.array([[1, 2, 3],
                            [4, 5, 6], 
                            [7, 8, 9]]),
                            index=['ONE', 'TWO', 'THREE'])
df
       0  1  2
ONE    1  2  3
TWO    4  5  6
THREE  7  8  9

df = pd.DataFrame(np.array([[1, 2, 3],
                            [4, 5, 6], 
                            [7, 8, 9]]),
                            columns=['A', 'B', 'C'],
                            index=['ONE', 'TWO', 'THREE'])
df
       A  B  C
ONE    1  2  3
TWO    4  5  6
THREE  7  8  9

2. Dictionary (+index)

df = pd.DataFrame({'A': [1, 2, 3],   → 이게 하나의 열임. Excel의 세로축
                   'B': [4, 5, 6],
                   'C': [7, 8, 9]},
                   index=['ONE', 'TWO', 'THREE'])
  
df
       A  B  C
ONE    1  4  7
TWO    2  5  8
THREE  3  6  9


df['열이름'] # 특정 열만 보여줌
df['A']
ONE      1
TWO      2
THREE    3

df['행이름'] # 불가능


df['열이름']['행이름'] # 특정 좌표값
print(df['A']['ONE'])
1

 열(column) 이름 가져오기

data_frame.columns.values.tolist() # 컬럼들을 리스트로 가져오기

 

● 행(index)으로 조회

df.values # 각 행을 리스트로 묶어서 가져옴
[[1 4 7]
 [2 5 8]
 [3 6 9]]
 
df['행이름']      # 불가능
df['ONE']        # 불가능
df['ONE'].values # 불가능

df.loc['ONE']
A    1
B    4
C    7

● 열(column)로 조회

df['열이름']             # 특정 열만 가져오기
df[['열이름1','열이름2]] # 여러 열 가져오기

df['열이름'].values     # 특정 열을 리스트로 묶어서 가져옴
df['A'].values
[1 2 3]

 

● 행(index) 추가

# 행 추가
df = df.append(df.iloc[-1], ignore_index=True)
df.iloc[-1] = row

또는
df = df.append(pd.Series(row, index=df.columns), ignore_index=True)

● 인덱스를 칼럼으로 추가

df['index'] = df.index

 

● 반복

dff = pd.DataFrame(np.array([[11, 21, 31], 
                            [12, 22, 32],
                            [13, 23, 33]]), 
                            columns=['A', 'B', 'C'],
                            index=['ONE', 'TWO', 'THREE'], )
print(dff['A'].values)
[11 12 13]


for column in df:
	print (column)
# A
# B
# C

for column in df:
	print (df[column])
# ONE      11
# TWO      21
# THREE    31
# Name: A, dtype: int64
# ONE      12
# TWO      22
# THREE    32
# Name: B, dtype: int64
# ONE      13
# TWO      23
# THREE    33
# Name: C, dtype: int64

for column, item in df.iteritems():
	print (item) = df[column] 과 동일
# item[0] 또는 item['ONE'] 또는 item.ONE 로도 값 출력도 가능



# index = 열이름
# row = 행이름 값 2개가 찍힘
# row['A'] 또는 row[0] 또는 row.A 로도 값 출력가능

for index, row in df.iterrows():
	print(index)
	print(row)
# ONE
# A    11
# B    12
# C    13
# Name: ONE, dtype: int64
# TWO
# A    21
# B    22
# C    23
# Name: TWO, dtype: int64
# THREE
# A    31
# B    32
# C    33
# Name: THREE, dtype: int64


# 값이 튜플일때 사용함 위와 다 똑같음
for row in df.itertuples():
   
# 열 반복하면서 특정 행만 출력
for v in df['A']:
    >> 11
    >> 12 
    >> 13

# 여러 컬럼 지정해서 출력
for a, b in zip(df['A'], df['B']):
    >> 11 21
    >> 12 22
    >> 13 23

● 형 변환 (type 변환)

pd.astype(dtype) # 모든 열의 데이터 타입 변경
pd.astype({'컬럼명':dtype}) # 특정 열의 데이터 타입 변경
dtype : 'int', 'float' 등등...

pd.dtypes() # 특정 열의 데이터 타입확인

 

● 문자열 조작

# 문자열 합치기
df['A'].str.cat(df['B'])
   >> 1121
   >> 1222
   >> 1323
   
# sep : 합치려는 문자 둘 사이에 문자 끼워넣기
df['A'].str.cat(df['B'], sep='-')
혹은 df['A'] + ' - ' + df['B']
   >> 11 - 21
   >> 12 - 22
   >> 13 - 23

# 숫자의 경우 형변환 필요 : astype()
df['A'].str.cat(['a', 'b', 'c'], sep=' - '))
astype()

df['ABC'].str.cat(['a', 'b', 'c'], sep=' - '))
혹은 df['ABC'] + ['a',b','c']
   >> a - a
   >> b - b
   >> c - c





# 행/열 이름 바꾸기
# rename(columns={'기존': '새거'}, index={'기존': '새거'})

# 기존 변수에 저장 ; inplace=True를 붙여야 함.
df.rename(columns={'A': 'a'}, index={'ONE': 'one'}, inplace=True)

# 새로운 변수에 저장
df_new = df.rename(columns={'A': 'a'}, index={'ONE': 'one'})

(s.rename(str.lower)) # 대문자를 소문자로 변경
s.add_prefix('X_') # 접주사 추가
s.add_suffix('_X') # 접미사 추가


# 문자열 검색 (대/소문자 구분함)
# 행 별로 검사해서 각 행마다 True/False로 반환
df['A'].str.contains('ABC')

# NaN 값이 있으면 True 또는 False로 변환
df['A'].str.contains('ABC', na=True 또는 False)

# 대/소문자 구분안하도록
df['A'].str.contains('ABC', case=False)

 

● 정렬

df.sort_values(by='정렬기준열이름', ascending = False, inplace = True)

 

# 행 순서 뒤집기

reversed_df = df.iloc[::-1]

 

# 이미 정렬된 배열을 반대로 뒤집기

df.iloc[np.argsort(df['foo'], kind="stable")]

 

● 비교 연산

df.loc[df.열이름.gt(0).idxmax()]

특정 열에서 0보다 큰 값 중에 젤큰거

DataFrame.eq : 요소별로 동일한 DataFrames를 비교

DataFrame.ne : DataFrames를 요소별로 비교

DataFrame.le : DataFrames를 요소별로 같지 않거나 같지 않은지 비교

DataFrame.lt : DataFrames를 요소별로 엄격하게 불평등보다 작은 지 비교

DataFrame.ge : 요소별로 부등식보다 더 크거나 같은 데이터 프레임을 비교

DataFrame.gt : 요소별로 부등식보다 더 큰 데이터 프레임을 비교

 

min() : 데이터 중 가장 작은 값 가져오기
max() : 데이터 중 가장 큰 값 가져오기
idxmin() : 데이터 중 가장 작은 값의 index 가져오기
idxmax() : 데이터 중 가장 큰 값의 index 가져오기

 

 

● 특정 열에서 처음 등장하는 양수값/음수값 가져오기

pandas.DataFrame :
df.열이름[df.열이름 >= 0].iloc[0] if df.열이름[df.exp >= 0].any() else df.열이름.max()
df.열이름[df.열이름 < 0].iloc[0] if df.열이름[df.exp < 0].any() else df.열이름.min()

pandas.Series : 
Series명[Series명 >= 0].iloc[0] if Series명[Series명 >= 0].any() else Series명.max()
Series명[Series명 < 0].iloc[0] if Series명[Series명 < 0].any() else Series명.min()

 


결측값 : None 또는 np.nan

- int/float형 : None 할당 → NaN 들어감

- str형 : None 할당 → None 들어감

 

● 결측값 확인

※ isnull() ↔ notnull() # 완전 반대

# 결측치 존재하면 True, 없으면 False
pd.isnull(df)
df.isnull()

# 결측치 존재하면 False, 없으면 True
pd.notnull(df)
df.notnull()

# 특정 컬럼에 결측치 존재하면 False, 없으면 True
df_all[['컬럼A', '컬럼B']].isnull() # A, B 컬럼 결측치 확인

# 결측치 개수 확인
df_all.isnull().sum() # 전체 대상 결측치 개수
df_all['컬럼명'].isnull().sum() # 컬러명 대상 결측치 개수
df_all.isnull().sum(1)      # 행 단위 결측값 개수
df_all.notnull().sum(1) # 열 단위 결측값 개수

 

● 결측값 있는 행/열 제거, 대체하기

import pandas as pd
import numpy as np
df.ix[0,0]=None
df.ix[0,1]=np.nan
→ 어떻게 할당해도 NaN으로 표기됨


# 결측값 제거
df.dropna() # 행/열 전체 제거
df.dropna(axis=0) # 행 전체 제거
df.dropna(axis=1) # 열 전체 제거


# 결측값 채우기/대체하기
df.fillna(채울값)               # df의 사본을 만들어서 결측값을 특정 값으로 채움
df.fillna(채울값, inplace=True) # df 원본의 결측값을 특정 값으로 채움

df.fillna(method='pad')   # 앞 방향으로 결측값 채우기 
df.fillna(method='ffill') # 앞 방향으로 결측값 채우기 
         a        b         c
0       NaN -0.111111  0.111111
1       NaN  0.111111       NaN  → 마지막 행부터 결측값 채워 나감

df.fillna(method='bfill') # 뒷 방향으로 결측값 채우기
         a        b         c
0       NaN -0.111111  0.111111 → 첫 행부터 결측값 채워 나감
1       NaN  0.111111       NaN

df.fillna(method='ffill', limit=number) # 앞 방향으로 결측값 채우기 (채우기 제한=number만큼)
df.fillna(method='bfill', limit=number) # 뒷 방향으로 결측값 채우기 (채우기 제한=number만큼)



# 결측값을 평균으로 채우기/대체하기
df.fillna(df.mean()) # 각 컬럼 평균으로 결측값 모두 대체하기
df.where(pd.notnull(df), df.mean(), axis='columns')

df.fillna(df.mean()['컬럼']) # 특정 컬럼 평균으로 결측값 모두 대체하기
df.fillna(df.mean()['컬럼A':'컬럼C']) # 컬럼A~C 평균으로 컬럼A~C에 있는 결측값 모두 대체하기

 

● 컬럼 전체합 

- 같은 DataFrame 내 같은 컬럼 간 연산 시 : 결측값(NaN)은 0으로 취급되어 연산됨

- 같은 DataFrame 내 다른 컬럼 간 연산 시 : 결측값(NaN)과의 연산값은 무조건 결측값(NaN)

- 다른 DataFrame 간 같은 컬럼 간 연산 시 : 결측값(NaN)은 0으로 취급되어 연산됨

- 다른 DataFrame 간 연산 시 한쪽DF에만 컬럼 없을 경우 : 결측값(NaN)과의 연산값은 무조건 결측값(NaN)

df.sum() # 컬럼별로 전체합
df['컬럼명'].sum() # 특정 컬럼의 전체합
df.cumsum() # 컬럼별로 전체 누적합
df['컬럼명'].cumsum() # 특정 컬럼의 전체 누적합

 

 

 


■ Pandas의 Input Output

  - 링크 : pandas-docs.github.io/pandas-docs-travis/reference/io.html 

 

 html에 있는 table속성에 해당하는 값 가져오기

웹페이지에 있는 표를 불러오겠다는 의미이다.

- 링크 : pandas-docs.github.io/pandas-docs-travis/reference/api/pandas.read_html.html#pandas.read_html

pandas.read_html(URL, match='.+',flavor=None,header=None,index_col=None, 
skiprows=None, attrs=None,parse_dates=False,tupleize_cols=None,thousands=', ',
encoding=None,decimal='.', converters=None,na_values=None,
keep_default_na=True,displayed_only=True)

• URL : 대상 url 입력
• match : str or compiled regular expression, optional
   : 정규표현식 또는 문자열을 이용해서 전체 테이블을 가져오지말고 
     원하는 내용이 들어있는 테이블만 가져오게 함.
• flavor = None / ‘bs4’ / ‘html5lib’
   : html을 parsing할 engine 선택. None일 경우 'lxml'으로 시도된 후,
     실패하면 bs4 + html5lib으로 수행된다.
• header = int or list-like or None, optional
   : header로(열 이름) 쓸 행을 지정할 수 있다.
• encoding = str or None, optional
   : 인코딩 설정. 한글이 깨져서 나올 때 encoding = 'utf-8'으로 설정하면 된다.

- 예시

df = pd.read_html(f'https://경로명', header=1)

 

 

● str을 pandas.DataFrame으로 변환

from pdb import set_trace as pb
if sys.version_info[0] < 3: 
    from StringIO import StringIO
else:
    from io import StringIO
    
input = StringIO(r.text)
df = pd.read_csv(input, sep=",", header = 0)

 

Excel 로 부터 Pandas DataFrame형식으로 읽어오기

- 함수 : pandas.read_excel()

- 링크 : pandas-docs.github.io/pandas-docs-travis/reference/api/pandas.read_excel.html#pandas.read_excel

read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, 
squeeze=False, dtype=None, engine=None, converters=None, true_values=None, 
false_values=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, 
na_filter=True, verbose=False, parse_dates=False, date_parser=None, thousands=None, 
comment=None, skipfooter=0, convert_float=True, mangle_dupe_cols=True, storage_options=None)

xlrd 라이브러리 사용하여 액셀에서 파일 읽어옴

- 예시

import pandas as pd
pd.read_excel('PATH') # Path상의 Excel의 첫번재 Sheet를 DataFrame형식으로 읽음
pd.read_excel('PATH', sheet_name=시트명or인덱스) # Sheet명or 인덱스(시작=0) 지정하여 읽음
pd.read_excel('PATH', sheet_name=[시트명or인덱스, 시트명or인덱스, ...]) # 여러 Sheet 읽기
>> ['시트명']=DataFrame
pd.read_excel('PATH', sheet_name=None) # 모든 Sheet 가져오기(Dictionary 형태로 가져옴)
>> ['시트명']=DataFrame


# Default는 1번 행=열이름, 1번 열=행이름으로 쓰임
pd.read_excel('PATH', header='열이름', index_col='행이름') # Header(열이름), Index(행이름) 설정
pd.read_excel('PATH', header=None, index_col=None) # Header/Index 없이 가져옴


pd.read_excel('PATH', usecols=[0, 1]) # usecol=[] 원하는 열만(A열=0, B열=1)

# 원하는 행만 가져오기 - 순서대로 0행 1행 2행 3행 이라고 생각하고 True인 행만 가져옴
mask = [True, False, True, False, True, False]
df_mask = df[mask]

# 조건에 부합한 행만 가져오기 
df_mask = df['age'] < 10 # 이것의 결과는 각 행별로 True False
df[df_mask]              # 집어넣으면 True인 행만 가져옴

### 연산자 ( NOT(~), AND(&), OR(|) 순서대로 우선순위)
df['age'] > 숫자
df['name'] == "문자열" 
~df['name'] == "문자열"
(df['age'] > 숫자) & ~(df['name'] == "문자열")
(df['age'] > 숫자) | ~(df['name'] == "문자열")


# skiprows=[] 지정한 행만 제외하고 다 가져오기 (0부터 시작)
df_use_skip = pd.read_excel('PATH', skiprows=[0])

# skipfooter=[] 마지막 행부터 올라오는 순서로 지정한 행 제외하고 다 가져오기 (1부터 시작)
df_use_skip = pd.read_excel('PATH', skipfooter=1)

 

Excel 에 Pandas DataFrame 형식을 저장하기

- 함수 : pandas.DataFrame.to_excel()

- 링크 : pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_excel.html

DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, 
columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, 
engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True, 
freeze_panes=None, storage_options=None)

내부적으로 xlwt 및 openpyxl이라는 라이브러리를 사용합니다.
둘 다 pip로 설치할 수 있습니다. (환경에 따라 pip3)
- xlwt는 .xls 파일을 작성하는 데 사용됩니다 (최대 Excel2003 형식).
- openpyxl은 .xlsx (Excel2007 이상 형식)를 작성하는 데 사용됩니다.

- 예시

import pandas as pd
pf = pd.DataFrame([데이터], index=[], colums=[])

df.to_excel('PATH', sheet_name='시트명', index=False, header=False)
# PATH : 해당경로에 파일 없으면 새로만듬, 있으면 덮어씌움
# sheet_name : 이거 안적어주면 시트명 Sheet1 이라고 만들어짐
# index, header : index(행이름), header(열이름) 지정해주기. 필요없으면 False로 주면 됨

 Excel여러 개의 Pandas DataFrame를 하나의 또는 여러 Sheet에 저장

- 함수 : pandas.ExcelWriter()

- 링크 : pandas-docs.github.io/pandas-docs-travis/reference/api/pandas.ExcelWriter.html#pandas.ExcelWriter

pandas.ExcelWriter(path, engine=None, date_format=None, 
datetime_format=None, mode='w', **engine_kwargs)

ExcelWriter() 사용하면 ExcelWriter오브젝트 생성됨
이 오브젝트는 하나의 액셀 파일처럼 사용하면 됨
DataFrame 여러개 or 같은 내용 여러 Sheet에 쓸때 사용

- 예시

import pandas as pd
import openpyxl
pf = pd.DataFrame([데이터], index=[], colums=[])

# ExcelWriter() 사용하면 ExcelWriter오브젝트 생성됨
# 이 오브젝트는 하나의 액셀 파일처럼 사용하면 됨
# DataFrame 여러개 or 같은 내용 여러 Sheet에 쓸때 사용
with pd.ExcelWriter('PATH') as writer:
    df1.to_excel(writer, sheet_name='sheet1')
    df2.to_excel(writer, sheet_name='sheet2')


# to_excel() 하면 아예 새 File에 새로 작성하여 덮어씌우는 반면,
# book() 사용하면 해당 파일에 계속 이어 쓸 수 있음.
with pd.ExcelWriter('PATH') as writer:
    writer.book = openpyxl.load_workbook(path)
    df.to_excel(writer, sheet_name='new_sheet1')
    df2.to_excel(writer, sheet_name='new_sheet2')

 

# 이동평균선 구하기

 

단순 이동평균선

pands.Series.rolling :

- 링크 pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.rolling.html

Series.rolling(window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None)

ex) N일 단순이동평균선 구하기

rolling(window=N).mean()

rolling(window=N, min_periods=1).mean() # 데이터 1개뿐일 경우라도 값 구하고 싶을 때

 

 

지수 이동평균선

- 링크 : pandas.pydata.org/docs/reference/api/pandas.DataFrame.ewm.html

DataFrame.ewm(com = None, span = None, halflife = None, alpha = None, min_periods = 0, 
adjust = True, ignore_na = False, axis = 0, times = None)

adjust=True : 지수이동평균 가중치 통해 초기값의 불균형 조정adjust=False

반응형