본문 바로가기
  • 문과생의 백엔드 개발자 성장기
|Playdata_study/Python

210722_Pandas (DataFrame)

by 케리's 2021. 7. 23.

DataFrame 생성

 

DataFrame은 2차원 배열 형식
표와 같은 스프레드 시트 자료 구조 (엑셀과 비슷)
여러개의 컬럼을 가지며 서로 다른 종류의 값(?)이 담긴다.

 

 

 

DataFrame 생성하는 방법

 

  • 리스트 값을 딕셔너리로 사용
  • Numpy 배열을 이용
  • read_csv, read_excel(),,, 함수사용

 

import numpy as np
import pandas as pd
from pandas import DataFrame,Series
import matplotlib.pyplot as plt

 

 

 

#  딕셔너리로 데이터 프레임 생성

 


딕셔너리의 key가 데이터 프레임의 column 값으로 들어간다?
여러 개의 컬럼을 가지면서 서로 다른 시리즈의 값이 담긴다.

중요!!! state, year, pop 는 각각의 series 이다
즉, 데이터프레임은 series의 결합체이다.
Series는 ndarray 클래스 타입으로 동일한 자료형이 요구된다.

 

 

# 1. 딕셔너리로 데이터 프레임 생성

'''
딕셔너리의 key가 데이터 프레임의 column 값으로 들어간다?
여러 개의 컬럼을 가지면서 서로 다른 시리즈의 값이 담긴다.

중요!!! state, year, pop 는 각각의 series 이다
즉, 데이터프레임은 series의 결합체이다.
Series는 ndarray 클래스 타입으로 동일한 자료형이 요구된다.

'''

dic = {'state' : ['Ohio','Ohio','Ohio','Nevada','Nevada','Nevada'],
        'year' : [ 2000,  2001,  2002,   2001,    2002,    2004],
        'pop'  : [ 1.5 ,  1.7,    3.6,    2.4,     2.9,     3.2]
       } # value 값을 list

dicDf = DataFrame(dic) # 위치 매개변수
dicDf

 

print(dicDf.state)
print(type(dicDf.state))
print('*' * 50)

print(dicDf.year)
print(type(dicDf.year))
print('*' * 50)


# pop 함수가 적용될 수 있으니 아래와 같이 사용하도록 하자

#print(dicDf.pop)
#print(type(dicDf.pop)) 

'''
<bound method DataFrame.pop of     state  year  pop
0    Ohio  2000  1.5
1    Ohio  2001  1.7
2    Ohio  2002  3.6
3  Nevada  2001  2.4
4  Nevada  2002  2.9
5  Nevada  2004  3.2>
<class 'method'>
'''



print(dicDf['pop'])
print(type(dicDf['pop']))

=========================================================

0      Ohio
1      Ohio
2      Ohio
3    Nevada
4    Nevada
5    Nevada
Name: state, dtype: object
<class 'pandas.core.series.Series'>
**************************************************

0    2000
1    2001
2    2002
3    2001
4    2002
5    2004
Name: year, dtype: int64
<class 'pandas.core.series.Series'>
**************************************************

0    1.5
1    1.7
2    3.6
3    2.4
4    2.9
5    3.2
Name: pop, dtype: float64
<class 'pandas.core.series.Series'>

 

 

1. 딕셔너리로 생성

 

data1 = {
    'name' : ['James', 'Peter', 'Tomas', 'Robert'],
    'address' : ['NY', 'TEXAS', 'LA', 'TEXAS'],
    'age' : [33, 44, 55, 66]
}

df1 = DataFrame(data1)
df1

 

 

 

2. Numpy배열 Data로 생성

 

 

위치 매개변수와 키워드 매개변수를 사용
()안에 data, index, column 입력가능 
data, index, column = 값, 이것을 keyword 매개변수라고한다

DataFrame은 2차원으로 만들어야함 (reshape사용)

 

# 위치 매개변수와 키워드 매개변수를 사용
# ()안에 data, index, column 입력가능 
# data, index, column = 값, 이것을 keyword매개변수라고한다

# DataFrame은 2차원으로 만들어야함 (reshape사용)
np.random.seed(100)
df2 = DataFrame(np.random.randint(10,100,16).reshape(4,4), #위치 매개변수
               index = list('abcd'),
               columns = list ('abcd')
               )
df2

 

 

# 컬럼명 수정 

 

# 컬럼명을 수정
df2.columns = ['one', 'two', 'three', 'four']
df2

 

 

 

3. read_csv() 함수로 생성

 

 csv 파일을 읽어들여서 생성 csv(comma-separated values)

 

df3 = pd.read_csv('../data/tips.csv')
df3

 

 

 

DataFrame 구조

 

 

1. 구조를 확인하는 속성

 

  • index
  • columns
  • values
  • dtypes → s를 붙여야한다!
  • info()
  • shape : 몇 행 몇열인지

 

 

 

# index

 

print(df3.index)

===============================

RangeIndex(start=0, stop=245, step=1)

 

# columns

 

print(df3.columns)

========================

Index(['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size'], dtype='object')

 

# values

 

print(df3.values)

===========================================

[[16.99 1.01 'Female' ... 'Sun' 'Dinner' 2.0]
 [10.34 1.66 'Male' ... 'Sun' 'Dinner' 3.0]
 [21.01 3.5 'Male' ... 'Sun' 'Dinner' 3.0]
 ...
 [17.82 1.75 'Male' ... 'Sat' 'Dinner' 2.0]
 [18.78 3.0 'Female' ... 'Thur' 'Dinner' 2.0]
 [25.34 nan nan ... nan nan nan]]

 

# dtypes

 

print(df3.dtypes)
# dtype 이 안되는 이유는 series의 결합체라서 되지 않음

======================================================

total_bill    float64
tip           float64
sex            object
smoker         object
day            object
time           object
size          float64
dtype: object

 

# info()

 

# 전체적인 dataframe에 column 대한 디테일한 정보
# 컬럼의 타입을 확인하고, info를 써서 한번에 null값이 존재하는지 (누락데이터가 존재하는지)먼저 확인하기 위해
# 분석 전에 info() 를 사용한다.

print(df3.info())

===========================================

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 245 entries, 0 to 244
Data columns (total 7 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   total_bill  245 non-null    float64
 1   tip         244 non-null    float64
 2   sex         244 non-null    object 
 3   smoker      244 non-null    object 
 4   day         244 non-null    object 
 5   time        244 non-null    object 
 6   size        244 non-null    float64
dtypes: float64(3), object(4)
memory usage: 13.5+ KB
None

 

 

 # T는 Transpose 의 약자, 행과 열을 바꿔준다.

 

print(df1.T) # T는 Transpose 의 약자, 행과 열을 바꿔준다!

==================================

             0      1      2       3
name     James  Peter  Tomas  Robert
address     NY  TEXAS     LA   TEXAS
age         33     44     55      66

 

df1 원본 df파일

 

 

 

 

 

2. 조회를 확인하는 함수

 

  • info()
  • head() : 앞 쪽 조회
  • tail() : 뒷 쪽 조회

 

 

 

# head()

 

df3
df3.head() # 앞에서 5줄만 가져온다
# df3.head(5), 위랑 같은 결과

 

df3.head(1) # 가져오고 싶은 숫자를 적는다

 

 

# shape

 

print(df3.shape) # 행과 열을 나타냄

====================================

(245, 7)

 

 

# tail()

 

df3.tail() # 뒤에서 5줄만 가져온다

 

 

DataFrame - 컬럼명 변경 및 추가하기

 

원본이 바로 변경되는 옵션과 원본이 변경되지 않는 옵션이 존재한다.

 

  • 컬럼명 전체 수정 : columns  ---> 원본 바로 변경
  • 컬럼명 부분 수정 : rename  ---> 원본 변경 되지 않음

 

 원본 데이터를 변경하려면 새로운 옵션을 하나 익혀야 한다.


   ★ inplace = True 를 추가 해야 한다.

 

 

 

1. 컬럼명 변경하기

 

df2

 

# 컬럼명 전체 변경하기 

# 1. 컬럼명 변경하기 (전체)
df2.columns = ['A-class', 'B-class', 'C-class', 'D-class']
df2

 

 

# 컬럼명 부분 변경하기 : rename

 

# 2. 컬럼명 변경하기 (부분)
# address -> addr
df1

df1 원본

 

# df1.rename(columns = {'address' : 'addr'}) # {'기존컬럼명':'새로운컬럼명'}

df1.rename(columns = {'address' : 'addr'}, inplace = True)
df1

 

 

2. 컬럼 추가하기

 

df1['phone'] = np.nan
df1

 

 

 

DataFrame - 데이터 검색하기

  • iloc
  • loc
  • at
  • iat

 

df2

 

 

df2.columns = ["one", "two", "three", "four"] # 다시 원래 컬럼으로 돌려놓았다
df2

 

 

슬라이싱 하는 방법


1) 정수형 슬라이싱
2) 라벨형 슬라이싱

 

 

1. row 데이터만 가져오겠다.

 

#   1) 정수형 슬라이싱
print(df2[0:2])

#   2) 라벨형 슬라이싱
print(df2['a':'b'])

======================================
   one  two  three  four
a   18   34     77    97
b   89   58     20    62
   one  two  three  four
a   18   34     77    97
b   89   58     20    62

 

 

2. column 지정 데이터 값 가져오기

 

#df2['one':'three'] # head값만 나옴
df2[['one','three']] # column 값

 

 

3. row를 가져오는데 특정 컬럼에 대한 row 가져오기 

 

print(df2[['two']])
print(df2[['two']] > 40)

=======================================

   two
a   34
b   58
c   76
d   25
     two
a  False
b   True
c   True
d  False

 

# iloc : 인덱스값을 선택해 원하는 값 가져옴

 

# iloc : 인덱스값을 선택해 원하는 값 가져옴
df2[df2['two'] > 40].iloc[:,1:2] # iloc [row, column]

 

df1

 

# 2,3번째 줄의 데이터를 iloc, loc로 가져와 보자

 

 

# iloc : 인덱싱으로 찾는방법 (가장 뒷자리 포함 안됨)
print(df1.iloc[1:3, 0:4])
print('*'*50)
print(df1.iloc[1:3, :4])
print('*'*50)
print(df1.iloc[1:3])
print('*'*50)

==========================================================
    name   addr  age  phone
1  Peter  TEXAS   44    NaN
2  Tomas     LA   55    NaN
**************************************************
    name   addr  age  phone
1  Peter  TEXAS   44    NaN
2  Tomas     LA   55    NaN
**************************************************
    name   addr  age  phone
1  Peter  TEXAS   44    NaN
2  Tomas     LA   55    NaN

 

 

# loc : 라벨명으로 찾는방법 (1:2모두포함)
print(df1.loc[1:2]) 
print('*'*50)
print(df1.loc[1:2,'name':'age'])

=================================================================

    name   addr  age  phone
1  Peter  TEXAS   44    NaN
2  Tomas     LA   55    NaN
**************************************************
    name   addr  age
1  Peter  TEXAS   44
2  Tomas     LA   55

 

 

# 스칼라 값 가져오기 iat, at

 

# iat

# 스칼라 값 가져오기 iat, at

print(df1.iloc[1:3])
print(df1.loc[1:2])
print('*'*50)
print(df1.iat[1,1])

=============================================

    name   addr  age  phone
1  Peter  TEXAS   44    NaN
2  Tomas     LA   55    NaN
    name   addr  age  phone
1  Peter  TEXAS   44    NaN
2  Tomas     LA   55    NaN
**************************************************
TEXAS

 

# at

# at 활용

# Tomas 나이 55세 출력
print(df1.at[2,'age'])
print('*'*50)

#Robert의 주소 TEXAS 출력 
print(df1.at[3,'addr'])

==============================================

55
**************************************************
TEXAS

 

 

# Tomas의 현재 나이가 55세, iat를 이용해서 Tomas의 나이를 50세로 변경하세요

 

df1.iat[2,2]=50
df1

 

 

# 5번째 row 추가, loc를 이용해서 , 값은 전부 누락데이터

 

# 5번째 row 추가, loc를 이용해서 , 값은 전부 누락데이터
df1.loc[4] = np.nan
df1

 

Data 삭제하기

  • drop()

 

# 마지막 row를 삭제한다

 

# 마지막 row를 삭제한다
df1.drop(4, inplace = True)

 

 

# phone에 해당하는 부분을 삭제하고 원본 반영

 

df1.drop('phone', axis =1, inplace = True)

 

 

DataFrame - 데이터 정렬하기

  • sort_index()
    orderby 와 같은의미, axis = 0 , 오름차순이 defalut값
  • sort_value()

 

df2

 

 

# sort_index()

 

df2.sort_index()

 

df2.sort_index(axis=1, ascending=False) # ascending 오름차순

 

df2.sort_values(by=['four'])

 

 

실전데이터로 응용하기

 

df3.head(3)

 

 

# 문제 1. tip 비율로 sort(많이 받은 팁이 윗쪽에 오도록), 샘플데이타 5개만

 

# 문제 1. tip 비율로 sort(많이 받은 팁이 윗쪽에 오도록), 샘플데이타 5개만

df3.sort_values(by=['tip'],ascending=False).head()

 

 

 

# Visualization

 

# Visualization

df3.sort_values(by=['tip'],ascending=False).head().plot(kind = 'bar')
plt.show()
# 숫자데이터만 표시, 성별,요일 표시되지 않음

 

 

# tip만 보는방법 

 

# tip만 보는방법 

df3.sort_values(by=['tip'],ascending=False).head()['tip'].plot(kind = 'bar')
plt.show()

 

 

# 문제 2. 요일별, tip별 정렬 각각 다르게 정렬
   day는 내림차순, tip은 오름차순
  마지막 데이타 7개만 디스플레이

 

# 문제 2. 요일별, tip별 정렬 각각 다르게 정렬
# day는 내림차순, tip은 오름차순
# 마지막 데이타 7개만 디스플레이

df3.sort_values(by=['day','tip'],ascending=[True,False]).tail(7)

 

 

중복 된 값을 배제하는 기능

  • unique()

 

df3['day']

=================================================

0       Sun
1       Sun
2       Sun
3       Sun
4       Sun
       ... 
240     Sat
241     Sat
242     Sat
243    Thur
244     NaN
Name: day, Length: 245, dtype: object

 

# unique()

df3['day'].unique()

=====================================

array(['Sun', 'Sat', 'Thur', 'Fri', nan], dtype=object)

 

 

 

# value_counts() : NaN은 count함수에서 제외된다.

 

df3['day'].value_counts() #NaN , count함수에서 제외된다.

==========================================

Sat     87
Sun     76
Thur    62
Fri     19
Name: day, dtype: int64

 

 

# isin() 특정한 데이타가 들어있는지 여부를 판단

 

df3['day'].isin(['Sat','Sun'])

===========================================

0       True
1       True
2       True
3       True
4       True
       ...  
240     True
241     True
242     True
243    False
244    False
Name: day, Length: 245, dtype: bool

 

 

# 문제 3. df3 데이터 프레임에서  목, 금요일에 해당하는 데이터만 추출

 

# 문제 3. df3 데이터 프레임에서  목, 금요일에 해당하는 데이터만 추출

# df3 # 전체데이터를 확인하고
# df3['day'].unique() # 어떤 요일이 존재하는지 모르기 때문에 중복제거를 한후 요일 확인하고

df3[df3['day'].isin(['Thur','Fri'])] #원하는 값 추출

 

 

# 문제4. isnull() 사용해서 컬럼별 누락데이터의 총 합을 출력

 

# 문제4. isnull() 사용해서 컬럼별 누락데이터의 총 합을 출력
# axis 값을 어떻게 부여하는 가에 따라서 결과가 완전히 달라진다!  중요!!
# df3.isnull().sum(axis=0)
df3.isnull().sum(axis=1)

========================================================

0      0
1      0
2      0
3      0
4      0
      ..
240    0
241    0
242    0
243    0
244    6
Length: 245, dtype: int64

 

 

df3.isnull().sum(axis=0).plot(kind='hist')

'|Playdata_study > Python' 카테고리의 다른 글

210723_Concat,Merge  (0) 2021.07.24
210722_NaN (누락데이터)  (0) 2021.07.23
210721_Pandas(Series, Matplot)  (0) 2021.07.23
210720_Numpy (array, random, 인덱싱, 슬라이싱)  (0) 2021.07.20
210512_웹 크롤링2  (0) 2021.05.12

댓글