Futureskill - Pandas Basic 2
Pandas
FutureSkill(https://www.futureskill.io) 에서 제출한 문제를 풀고 공부한 내용
DataFrame method
array = [[0 for col in range(4)] for row in range(12)]
for x in range(len(array)):
for y in range(len(array[x])):
array[x][y] = chr(y+65) + str(x)
columns = ['A', 'B', 'C', 'D']
df_B = pd.DataFrame(array, columns = columns)
print(df_B)
간단한 DataFrame을 만들어보았습니다. 피어리뷰를 구경하던 중 다음과 같은 코드를 봤습니다. (논문읽는재간둥이님 코드)
cols = ['A', 'B', 'C', 'D']
data = [[c+str(i) for i in range(12)] for c in cols]
df_b = pd.DataFrame(np.array(data).T, index=range(0, 12), columns=cols)
cols를 재활용해서 조금 더 직관적으로 data의 모양이 눈에 보이고, 결국 이를 전치(.T) 한 뒤에 DataFrame을 만들어주는 게 더 깔끔하고 멋져보였습니다.
DataFrame df_b(df_B)에서 데이터를 출력하는 방법을 연습했습니다. 우선 기본적으로 위에서부터 5개 행을 출력하는 코드는 다음과 같습니다.
df_b.head()
df_b[:5] # indexing operator 사용
df_b.loc[0:4,:]
df_b.iloc[0:5,:]
.loc가 있을 때는 0:4, 그냥 참조할 때, iloc를 사용할 때는 :5 로 잡아주고 있습니다.
간단하게 요약하면 다음과 같습니다.
.loc는 label based 이기 때문에 0:4 까지 출력해서 0, 1, 2, 3 ,4 로 5개를 출력할 수 있음..iloc는 integer position based 이기 때문에 0:5 까지 출력해서 0, 1, 2, 3, 4 로 출력할 수 있음.
→ 아마 행보다는 열을 뽑아낼 때 column의 이름(label), 위치(position)에 따라 다르게 쓸 수 있어 차이를 보기 더 쉬울 것 같습니다.
# A 열을 출력할 때
df_A.loc[:,"A"] # "A" label의 열
df_A.iloc[:,0] # 0번째 위치의 열
df_A['A'] # indexing operator 사용
df_A.iloc[1:4,0:2] # 1행 ~ 3행, 1열 ~ 3열 까지의 데이터를 출력
df_A.loc["2020-01-02":"2020-01-04","A":"B"]
DataFrame의 정보를 추출하는 몇개의 코드를 작성해보겠습니다.
df_B.index # index 출력
df_B.values # values 출력
df_B.columns # columns 출력
# 각각 df_B를 요약해주는 방법들
df_B.describe() # 통계량 출력
df_B.describe # df_B.info와 같은 역할
df_B.info() # 요약
df_B.info
describe 와 describe() 의 차이 :
describe() : method로 class 내의 함수.
descirbe : attributes(속성) 으로 다른 오브젝트를 참조하는 변수
→ 다른 기능을 보이고 있습니다. (나중에 알아보기.)
DataFrame의 정렬 또한 다음과 같이 간단하게 구현할 수 있습니다.
# df_A를 이용해서, column C 기준으로 내림차순 정렬한 결과를 출력하는 코드를 작성해보세요
df_A = df_A.sort_values(by=['C'], ascending=False)
오름차순은 ascending=True 로 바꿔주면 됩니다.
df_A에서 0보다 큰 데이터를 모두 출력하고, 그렇지 않은 경우 NaN(Not a Number)로 출력하는 코드는 다음과 같습니다.
df_A[df_A > 0]
DataFrame 두 개를 위-아래로 합치는 코드를 작성해보겠습니다.
col = list('ABC')
A = pd.DataFrame([[1,3,5],[2,4,6]],columns=col) # A Dataframe
B = pd.DataFrame([[-1,-3,-5],[-2,-4,-6]],columns=col) # B Dataframe
# axis = 0 : 가로축을 기준으로 합친다. -> 위, 아래
# axis = 1 : 세로축을 기준으로 합친다. -> 오른쪽, 왼쪽
# ignore_index = True : 합치고 나서 인덱스를 무시한다.
frames = [A, B]
C1 = pd.concat(frames,axis = 0,ignore_index=True)
.concat과 비슷한 기능을 하는 append도 있습니다. 하지만 여러개를 합치는 게 불가능하고, axis 값을 줄 수 없는 등 기능이 더 적습니다.
C2 = A.append(B, ignore_index = True)
merge는 데이터베이스에서 join을 반영한 병합방식입니다. (SQL)
C3 = pd.merge(A,B,how="outer")
Read/Write panel data
panel data는 xlsx, csv와 같은 테이블 형식의 정형 데이터로, tabular data, structured data 라고도 부릅니다. csv 파일은 comma spread value의 약자로 확장성이 좋아 많은 경우 표준이 됩니다.
└── workspace
└── train.csv
└── report.xlsx
└── solution.py # (or solution.ipynb)
현재 폴더의 위치는 workspace라고 표기하였습니다.
작성중인 코드파일의 이름을 solution 이라고 표기하였습니다.
작성중인 코드파일과 동일한 폴더에 위치하게끔 파일을 옮기세요.
'코드파일과 데이터의 폴더'에 대한 개념도 문제에 포함되어 있습니다.
다음과 같이 코드파일과 데이터의 폴더가 같은 폴더에 있을 때, .csv, .xlsx 파일을 불러오는 코드는 다음과 같습니다.
df_E = pd.read_csv('train.csv')
df_F = pd.read_excel('report.xlsx')
이번에는 코드 작성 후, 같은 디렉토리 내에 폴더(result)를 만들고 내부에 수정된 데이터를 train(edited).csv로 저장하는 코드를 작성해보겠습니다.
├── result
│ └── train(edited).csv
├── train.csv
└── solution.py # (or solution.ipynb)
df_E = df_E.drop(columns=['PassengerId', 'Name', 'Ticket']) # 해당 열 삭제.
df_E.to_csv('result/train(edited).csv')
데이터를 불러와 NaN 값을 처리하는 코드를 작성해보겠습니다.
df_C = pd.read_excel('toy.xlsx')
df_C = df_C.dropna() # NaN값 삭제.
df_C = df_C.fillna(method='ffill') # NaN 값을 앞의 값으로 채운다.
df_C.fillna(df_C.mean()) # NaN 값을 해당 열의 평균값으로 채운다.
df_C = df_C.fillna(np.nanmean(df_C)) # NaN 값을 데이터 전체의 평균으로 채운다.
마지막 전체의 평균으로 채우는 경우, 처음에는 df_C.fillna(df_C.mean().mean())과 같이 작성을 했는데, 이 경우 평균값을 제대로 구하지 못한다.
df_c.mean() 에서 평균값을 계산할 때는 NaN을 제외하고 계산.(np.nanmean과 같은 방식) 이 값을 다시 평균을 내면(df_C.mean().mean()) 열 갯수의 값으로 나눠주게 되는데 여기서는 NaN을 제외하지 않으므로 오류가 생긴다.
Aggregating
각 행의 평균을 저장하고 있는 열을 만들고, 열의 이름을 “평균”으로 지정하는 코드와 각 열마다의 합계를 구하고 마지막 행에 추가하는 코드를 작성해보겠습니다.
data = [[1, -1, 2], [2, -2, 3], [3, -3, 4], [4, -4, 7], [5, -5, 8]]
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
df['평균'] = df.agg("mean", axis="columns") # "sum", "min" 등 다양한 방법이 존재.
print(df)
df = df.append(df.agg("sum"), ignore_index=True)
print(df)
df_D['평균'] = df_D.mean(axis=1)와 같이 .agg를 사용하지 않을 수도 있습니다.
Groupby, pivot table
data = [[1, -1, 2], [2, -2, 3], [3, -3, 4], [4, -4, 7], [5, -5, 8]]
df = pd.DataFrame(data, columns=['val1', 'val2', 'val3'])
df['label'] = ['A', 'A', 'B', 'B', 'B']
print(df.groupby(by=['label']).sum())
label 을 기준으로 합을 구하는 코드입니다.
pivot table은 다음과 같이 pivot_table, groupby를 이용해 만들 수 있습니다.
table = pd.pivot_table(df, index=['label'], aggfunc=np.mean)
df1 = df.groupby('label').mean()
aggfunc의 경우 다음과 같이 여러개의 방법을 사용할 수 있습니다.
- aggfunc = [‘sum’, ‘count’…] 와 같이 리스트로 처리하면 된다.
- aggfunc = [sum, count…] 와 같이 리스트로 처리하면 된다.
- aggfunc = [np.sum,…]와 같이 numpy를 불러와서 처리할 수 있다
Leave a comment