14. pandas 데이터분석 해보기(파일읽기, 분석 3가지(고난도), 파일쓰기)
파일 읽기(csv)
이전 numpy의 파일 읽는 방법을 복습해보자.
data = np.loadtxt("data/movielens-1m/ratings.dat", delimiter = "::", dtype = np.int64)
np.savetxt("mean_rating_by_user.csv", mean_rating_by_user_array, fmt='%.3f', delimiter=',')
pandas에서 파일을 읽는 방법은, pd.read_csv()함수를 사용하여 –> DataFrame으로 자동으로 가져온다.
인자에는 간단하게 “파일경로”와 구분자를 sep = “,” 를 지정해준다.
파일 경로는 홈화면에서 파일을 따라간 뒤, 주소창에 있는 것을 복사해오면 간단하다.
이 때, dtype오류가 나서 마지막 인자 dtype = ‘unicode’를 붙혀줬더니 정상적으로 가져와졌다.
data = pd.read_csv("data/lending-club-loan-data/loan.csv", sep="," , dtype='unicode')
데이터를 가져오는데 시간이 걸려서 난 오류라고한다. 무시하고 dtype안붙혀줘도 된다.
data = pd.read_csv("data/lending-club-loan-data/loan.csv", sep=",")
- 자료는 lengding-club에서 제공해주는 대출정보다.
DataFrame 분석해보기
- **** csv – > dataFrame으로 가져왔으면 처음으로 해야할 일은, shape와 몇 행의 데이터를 살펴보는 것이다.
먼저 shape를 보자. data.shape
shape를 보니, 행이 88만개 / 열이 74개 이다. - 이제 열을 구체적으로 보기 위해서, data.columns를 확인한다. 너무 많으므로, 우리에게 유의미한 것만 가져와 써야한다.
- loan_amnt: 대출자의 대출 총액
- loan_status: 대출의 현재 상태*
- grade: LC assigned loan grade**
- int_rate: 대출 이자율
- term: 대출 상품의 기간 (36-month vs. 60-month)
- 필요한 열만 떼어네서, 새로운 DataFrame 변수에 넣어보자. 여러 칼럼을 인덱싱할 때, 리스트의 형태로 넣어줘야한다.
“loan_amnt”, “loan_status”, “grade”, “int_rate”, “term” 열만 가져온다. - shape를 파악했으면 이제 앞, 뒤 5개행만 볼 수 있는 df2.head()함수 df2.tail()함수로 확인한다.
- 데이터를 보고, loan_amnt , int_rate에는 숫자정보 / loan_status, grade, term에는 문자열 정보가 있는 것을 확인한다.
(shape->필요한 열만 뽑아내기–> head/tail –> 각 열의 데이터타입 눈으로 확인) - 문자열 정보를 가진 열(칼럼)에 대해서 데이터가 범주형인지 아닌지 .unique() 함수로 확인해야한다.
(파일읽기–> shape-> columns확인–> 필요한 열만 뽑아내기–> head/tail –> 각 열의 데이터타입 눈확인 –> 문자열 데이터 범주확인) - 결측값(NaN)을 포함한 행들 제거시키기 위해서 .dropna(how=”any”)함수를 이용한다.
만일 NaN가 존재하여 shape로 살펴봤는데, 행의 개수가 줄어들었으면, 뽑은 것으로 새로운 df를 만들어야할 것이다.
(파일읽기–> shape-> columns확인–> 필요한 열만 뽑아내기–> head/tail –> 각 열의 데이터타입 눈확인 –> 문자열 데이터 범주확인 –> 결측값(NaN) 제거 후 shape확인)
즉, 어떤 csv파일을 받아서 DataFrame으로 받았을 때, 기본적인 분석은
파일읽기–> shape/head-> .columns확인–> 필요한 열만 뽑아낸 df 만들기–> head/tail –> 각 열의 데이터타입 눈확인 –> 문자열 데이터 범주확인 –> 결측값(NaN) 제거 후 shape확인
의 과정을 거쳐야한다.
데이터분석 1 – 대출기간(term)에 따른 대출총액(loan_amnt) 파악하기
[ 기준열: 범주형 문자열데이터 – 각 성분에 따른 특정열의 총합 각각 구해서 담기 ] : 각 성분에 따른 것은 for문에 들어갈 것임
해당자료에는 term에 문자열정보로서, 36개월 대출과 60개월 대출 2가지 범주가 존재한다.
여기서 term열의 2가지 데이터를 기준으로 –> 전체 대출 총액(loan_amnt)을 확인해보자.
- 각 기간에 따른 대출총액의 합을 for문을 돌면서 하나씩 저장해줄 빈 딕션너리를 생성한다.(term_to_loan_amnt_dic)
- term 열에 대해 중복없는기준열을 변수로 만든다. 36개월과 60개월이 나올 것이다. (uniq_terms)
- 중복없는 기준열인(uniq_terms)가 for문안에서 하나씩(term)로 대입되면서 for반복문을 만든다. 이 때, term은 전체기준열 안에 있는 특정성분을 의미한다.
- term열 중 특정성분으로 작용할 term으로 df[“term”]열에 대한 마스크를 만들고,
그것을 df2.loc[]의 행 인덱스에 집어넣는다.(DataFrame에서 행과 렬을 동시에 인덱싱하는 loc만 가능),
여기까지는 조건에 맞는 행들만 골라내진 상태이므로, 기준에 따라 불러오고 싶은 열을 인덱스로 준다. 즉, “loan_amnt” 열만 넣어준다.
각, 특정term을 만족시키는 행(36또는 60개월)이 여러(n)개 있고 -> 불러온 “loan_amnt” 1개의 열이므로
nx1의 dataFrame을 이룰것이다. (Series형태다. 1차원 nx1)
예를 들어,
(term-열인덱싱x 생략됨) “loan_amnt”
01행 –( 36 months ) 3만원
32행 –( 36 months ) 76만원
51행 –( 36 months ) 21만원
for문에 마스크로 행index에 집어넣어 원하는 행들을 뽑아내면 –> n행
열index에 집어넣은 우리가 필요한 열이 1개면, n x 1 (Series형태) / 2개면 n x 2 DataFrame형태
이러한 n x 1 DataFrame을 .sum()함수로 모든 성분을 더하면 –> 36months에 대한 “loan_amnt”의 총액이 계산된다.
그 값을 loan_amnt_sum 변수에 넣어준다. for문을 돌면, 36개월에 대한 대출총액 / 60개월에 대한 대출총액 2개가 담길것이다. - 이제 for문을 돌면서, 각 unique한 term마다, 대출총액을 모두 더한 loan_amnt_sum을
1번에 만든 빈 딕셔너리(term _to_loan_amnt_dict)에 담을 것인데,
각 조건성분인 term을 딕셔너리의 [열이름]형태로 열 인덱싱하여 새로운 열(키값)을 생성하면서 & 동시에 윗줄에서 계산된 모든 대출총액을 더한 값들을 대입하여 키값으로 만든다. 예를 들면, 36개월에 대한 대출금액 총합을 –> 딕셔너리의 키값에 대한 벨류값으로 넣을 것이다.
(딕셔너리에다가 열인덱싱을 통해서 키값이 생성되고 = 우항이 밸류값이 된다)
( 10강 : 딕셔너리 { 키값 : [밸류1, 밸류2,] , 키값2 : [밸류3, 밸류4] } –> DataFrame.columns : 키값, 키값2 , 행 갯수 : 리스트성분 수)
for문을 돌면서 들어오는 term열의 특정성분(36 or 60)으로 하는 열인덱싱의 열이 –> { 키값 : }
들어간 term마다 대출총액 – > { : 밸류값} 이 될 것이다.
***9강 numpy의 데이터분석에서는 빈 리스트[]를 생성하고, for문을 돌면서, 거기다가 1차원임에도 불구하고,
리스트안에 다시[ 성분1, 성분2]의 리스트를 만들고 –> 리스트안에 [ [리스, 트] ]를 만들것을 np.array로 넣기만 하였더니
M x N으로 바로 사용할 수 있었다.
- for문을 돌면서 하나씩 받기 위해서 빈 딕셔너리를 만들고, 거기다가 { 키값 : 밸류 } 형태로 채웠던 것을,
편하게 데이터를 관리하기 위해 1차원 딕셔너리( 1행(밸류 성분수) x n열(키값들)) –> Series에 담아준다.
*** 딕셔너리 키값 수 = 열 수 , value리스트 수 = 행 수 였는데 지금 value값이 하나밖이므로, 행도 1개다.
*** 행 1개 인 것이 바로, 1xn 의 1차원 Series다. 그래서 키값 = 열 수 가 아니라 1차원형태의 행 index가 된다.
*** 즉, 다시 정리하자면, 딕셔너리 中{키값 : 밸류값}의 밸류가 1개 뿐인 것은 1차원 Series로 바꿀수 있으며, 키값=>index가 된다.
만약 딕션너리가 키값 : [밸류1, 밸류2 .. ] 등 여러개가 되면, 키값=> 열 / 리스트성분의 수 => 행수인 DataFrame이 된다.
my) Series는 인덱스를 인자로 주는 장점이 있다. 즉, 열은 없다. 시리즈로 전환되는 밸류1개의 딕셔너리에서 키값= 행index
=> 파일 읽고 기본적인 분석하기 :
파일읽기(.read_csv)–> shape/head-> .columns확인–> 필요한 열만 뽑아낸 df 만들기–> head/tail –> 각 열의 데이터타입 눈확인 –> 문자열 데이터 범주확인 –> 결측값(NaN) 제거 후 shape확인
=> 기준열에 특정성분 따른(term-2가지 문자열) 특정열의 합(loan_amnt 총합) 파악하기 :
기준열의 문자형데티어 범주확인 –> 빈 딕셔너리{ }생성-> 중복없는 기준열 변수 생성 –> for문 안에서, 마스크로 중복없는 기준열의 각 성분에 따른 특정열만 뽑고, 가상으로만들어진 nx1의 총합 계산후 변수에 담기 –> 각 성분을 딕셔너리[ 열이름]으로 인덱싱하여 딕셔너리의 키값으로 생성 = 우항에 키값에 대한 총합 변수 대입으로 밸류값 생성 –> 생성된 { 키값1:밸류값1 , 키값2:밸류값2 }의 밸류값이 1개로 구성된 1xn 1차원 딕션너리를 1차원인 Series에 담기
데이터분석 2 – 대출상태(loan_status)중 불량상태에 해당하는 사람들의 대출등급(grade) 파악하기
[ 기준이 범주형 문자열데이터-> 일부성분만 떼내서 분류 –> 일부성분만 가진 행들에 대해 특정열 분포확인] : 각 특정성분x-> for문 x
- 분석에 앞서 기본적으로, 들고 있는 DataFrame의 head() 확인
- 문자형데이터로 구성된 기준열의 범주 확인 –> 의미상 불량상태 / 우량상태를 확인할 수 있다.
- 기준열을 중복없는 기준열 변수 생성 (total_status_category)
- 기준열의 범주(2)를 바탕으로 –> 중복없는기준열(1차원 array)에 index를 사용한 인덱싱으로 특성성분들(불량상태) 만들기
(1) 불량상태 (bad_status_category) : bad_status_category = total_status_category[ [1,3,4,5,6,8 ] ] - 기준열.isin( 특정성분들)을 이용해서, 불량상태에 따른 기준열의 마스크를 만들어 df2에다가 새로운 열로 추가한다.
df2[“bad_loan_status”] 열이 추가되었으면, head()로 새로운열을 확인한다.
df2["bad_loan_status"] = df2["loan_status"].isin(bad_status_category)
기준열 중에, bad_status_category라는 특정성분들을 가지고 있으면, 새로운열에는 True라고 표시가 된다. - 이제 bad_loan_status 열에 True(불량상태의 loan_status)를 가진 행들에 대해 grade의 분포를 살펴보기 위해,
for문안에서 중복없는 기준열의 특정성분으로 마스크를 비교하는 것이 아니라, for문 없이
(1)불량상태를 기준으로 만든 열 마스크(bad_loan_status)==True를 행 index에 집어넣어, 행들을 골라내고
(2) 그 행들에 대한 “grade”열만 가져온다. –> 골라낸 행들 x “grade”열 의 nx1 형태의 DataFrame이 가상으로 생긴다. nx1의 dataFrame을 이룰것이다. (Series형태다. 1차원 nx1) - Series의 index(열은 없다)를 보기좋게 하기 위해, sort_index()함수로 오름차순으로 정렬해준다.
- 대출상태가 우량상태인 경우를 뽑으려면, 불량상태와 정반대로만 하면된다. 즉, 마스크 == False로 뽑아내서 담아주면된다.
예를 들어,
(행인덱싱의 True) “grade”
01행 –( True ) B
32행 –( True ) C
51행 –( True ) A
(3) 그렇게 뽑아낸 df에 value_counts() 함수를 사용하여, grade열의 각 성분들에 대한 행의 갯수가 Series의 형태로 얻어진다.
그것을 새로운 변수 bad_loan_status_to_grades 에 담는다.
=> 기준열의 일부성분들을 가진 행들을 골라내어 그 행들의 특정열 분포 확인하기
헤더확인-> 범주 확인후 중복없는 기준열 변수(total category)생성 -> 일부성분만 index로 열 인덱싱한 일부성분기준열 변수 생성(bad category) -> 전체기준열에 isin( 일부성분기준열)을 통해, 마스크생성한 것을 새로운 열로 추가( df[ 새로운 마스크 열 ]) -> 행인덱스에 마스크==True를 통해 행들을 골라낸 후, 열인덱스에 특정열만 골라내어, 가사의 nx1의 Series획득한 상태에서 .value_counts()를 입혀 Series[ 특정열값 - 행 수 ]의 변수(bad_to_grade) 생성 -> Series를 오름차순 정렬 -> good category를 원하면 마스크 ==False로 구함
데이터분석 3 – 대출총액(loan_status)과 대출이자율(int_rate) 간의 상관관계 분석 [ 숫자-숫자 데이터]
분석하기 앞서, 정리된 데이터의 head()를 살펴본다.
- 기준열인 df2[“loan_amnt”]과 .corr ( 비교열 df2[“int_rate”] )함수를 통해 상관계수를 뽑아낸다.
*** 문자형정보를 가진 열을 비교하면 먹통이 된다.
상관관계 분석하기 :
기준열. corr( 특정열 )
파일 쓰기
파일 읽기는 : data = pd.read_csv("data/lending-club-loan-data/loan.csv", sep="," ) 였다.
bad_loan_status_to_grades 에 정리된 자료를 .to_csv()를 호출하면서
첫번째 인자에는 파일명,
두번째 인자는 구분자를 입력해준다.
bad_loan_status_to_grades.to_csv(“bad_loan_status.csv”, sep="," )
파일쓰기 : to_csv()
'빅데이터 관련 프로그래밍 > Python - bigdata(pandas 기초)' 카테고리의 다른 글
15. Matplotlib 사용하기 –라인 플롯, 바 플롯, 히스토그램, 산점도 (1) | 2018.02.25 |
---|---|
참고 : pandas 분석 정리 (0) | 2018.02.25 |
13.Pandas DataFrame 데이터분석용 함수(통계함수, 정렬함수, 유용한 함수, 사용자정의함수 적용) (2) | 2018.02.24 |
12. pandas DataFrame 조작하기(datatime데이터형 / 결측값,이상치(NaN)/열 조작/ 행 조작) (5) | 2018.02.24 |
11. pandas DataFrame 인덱싱(열 / 행 / boolean 인덱싱) (7) | 2018.02.24 |