본문 바로가기
ML&DATA/python for data analysis

pandas - (Series, DataFrame, Index)

by sun__ 2020. 7. 19.

 

5.1 pandas 자료구조

 

5.1.1 Series
series는 일련의 객체를 담을 수 있는 1차원 배열 같은 자료구조. index(색인) 이라고 하는 배열의 데이터와 연관된 이름을 갖고 있음. 고정길이의 정렬된 사전형이라고 생각할 수 있다. 연산은 numpy연산처럼 적용된다.

 

values속성으로 Series의 배열을 얻을 수 있고, index속성으로 인덱스 객체를 얻을 수 있다.

 

배열 혹은 사전으로부터 생성될 수 있다.

ex) 사전으로 Series 생성 후 index만 바꾸는 예제

California 인덱스를 추가했는데 해당 값이 없으므로 Not a Number값 받음. 누락된 데이터를 의미함.

sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)
obj3
#out:
#Ohio      35000
#Texas     71000
#Oregon    16000
#Utah       5000
#dtype: int64

states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)
obj4
#out:
#California        NaN
#Ohio          35000.0
#Oregon        16000.0
#Texas         71000.0
#dtype: float64

 

 

numpy와 마찬가지로 boolean형 values를 갖는 series로 series를 선택할 수 있다.

obj2 = pd.Series([4, 7, -5, 3])
obj2
#out:
#0    4
#1    7
#2   -5
#3    3
#dtype: int64

obj2[obj2>0]
#out:
#0    4
#1    7
#3    3
#dtype: int64

 

 

두 개의 Series에 대해 연산 시 sql의 join과 비슷한 면이 있다.

obj3
#out:
#Ohio      35000
#Texas     71000
#Oregon    16000
#Utah       5000
#dtype: int64

obj4
#out:
#California        NaN
#Ohio          35000.0
#Oregon        16000.0
#Texas         71000.0
#dtype: float64

obj3+obj4
#out:
#California         NaN
#Ohio           70000.0
#Oregon         32000.0
#Texas         142000.0
#Utah               NaN
#dtype: float64

 

 

 

Series 인덱스와 Series 객체 자체는 모두 name속성이 있다. pandas의 핵심기능과 밀접함.

obj4.name = 'population'
obj4.index.name = 'state'
obj4
#out:
#state
#California        NaN
#Ohio          35000.0
#Oregon        16000.0
#Texas         71000.0
#Name: population, dtype: float64

 

 

 Series의 인덱스는 대입연산으로 변경할 수 있다.

obj2
#out:
#0    4
#1    7
#2   -5
#3    3
#dtype: int64

obj2.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
obj2
#out:
#Bob      4
#Steve    7
#Jeff    -5
#Ryan     3
#dtype: int64

 

 

 

5.1.2 DataFrame

표 같은 스프레드시트 형식의 자료구조이다. 여러 개의 컬럼이 있는데 각 컬럼은 서로 다른 타입의 값을 담을 수 있다.  색인의 모양이 같은 Series 객체를 담고있는 딕셔너리라고 생각할 수 있다.

 

파이썬 사전이나 numpy배열을 이용하여 생성할 수 있다.

 

ex) 사전으로 DataFrame 생성

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002, 2003],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
frame

 

ex) numpy배열로 DataFrame생성

frame = pd.DataFrame(np.arange(9).reshape((3,3)),
                    index = ['a','c','d'],
                    columns = ['Ohio', 'Texas', 'California'])
frame

 

 

원하는 순서대로 columns을 지정하여 생성할 수 도 있다.

pd.DataFrame(data, columns=['year','state', 'pop'])

 

 

index의 이름도 정해줄 수 있다. 이 때 사전에 없는 값을 넘기면 NaN으로 저장된다. columns속성으로 컬럼의 정보를 알 수 있다. 

frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
                      index=['one', 'two', 'three', 'four',
                             'five', 'six'])
frame2.columns
#out: Index(['year', 'state', 'pop', 'debt'], dtype='object')
frame2

 

컬럼별로 접근하는 것이 가능하다. 괄호로 접근하거나 속성 형식으로 접근할 수 있다. 컬럼의 타입은 Series이다.

frame2['state']
#out:
#one        Ohio
#two        Ohio
#three      Ohio
#four     Nevada
#five     Nevada
#six      Nevada
#Name: state, dtype: object 

frame2.year
#out:
#one      2000
#two      2001
#three    2002
#four     2001
#five     2002
#six      2003
#Name: year, dtype: int64

 

로우별로 접근하는 것도 가능하다. loc속성을 이용해서 인덱스의 이름을 통해 접근할 수 있다. 로우의 타입도 Series이다.

frame2.loc['three']
#out:
#year     2002
#state    Ohio
#pop       3.6
#debt      NaN
#Name: three, dtype: object

 

컬럼의 값을 변경할 수 있다. 현재 'dept' 컬럼에 스칼라값이나 배열값을 대입할 수 있다.

frame2['debt'] = 16.5
frame2
frame2['debt'] = np.arange(6.)
frame2

 

 

리스트나 배열을 컬럼에 대입할 땐 그 길이가 DataFrame의 길이와 반드시 동일해야 한다. Series는 길이가 안맞아도 대입은 되지만 존재하지 않는 index엔 결측치가 대입된다.

frame2['debt'] = [1,2,3,4,5]	#!!error!!

val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame2['debt'] = val
frame2

 

존재하지 않는 컬럼을 대입하면 새로운 컬럼을 생성한다. 

ex) state컬럼의 값이 'Ohio'이면 True인 불리언값을 담고있는 새로운 컬럼 'eastern'

frame2['eastern'] = frame2.state=='Ohio'
#frame2.eastern = frame2.state=='Ohio' ::: !!error!!
frame2

del예약어로 컬럼을 삭제할 수 있다. 

del frame2['eastern']
frame2.columns
#out : Index(['year', 'state', 'pop', 'debt'], dtype='object')

 

DataFrame에서 얻은 컬럼 데이터는 내부 데이터에 대한 view이다. 이렇게 얻은 Series객체에 대한 변경은 실제 DataFrame에 반영된다. 복사폰이 필요할 땐 copy메서드를 이용하면 된다.

 

 

중첩된 사전을 이용해서 DataFrame을 생성할 수 있다. 바깥에 있는 사전의 키는 컬럼이 되고 내부 사전의 키는 로우가 된다.

pop = {'Nevada': {2001: 2.4, 2002: 2.9},
       'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}

frame3 = pd.DataFrame(pop)
frame3

 

데이터의 전치할 수 있다.

frame3.T

 

중첩된 사전으로 DataFrame을 생성할 때 index를 미리 정해준다면 row는 내부사전의 키와 정해준 index의 join꼴이 된다. 

pd.DataFrame(pop, index=[2001,2002,2003])

 

Series객체를 값으로 갖는 사전으로 DataFrame을 만들 수 있다.

pdata = {'Ohio': frame3['Ohio'][:-1],
         'Nevada': frame3['Nevada'][:2]}
pd.DataFrame(pdata)

 

index와 column에 name속성을 지정할 수 있다.

frame3.index.name = 'year'; frame3.columns.name = 'state'
frame3

 

value속성은 DataFrame에 저장된 데이터를 2차원 배열로 반환한다. 만약 컬럼이 서로 다른 dtype을 가지고 있다면 모든 컬럼을 수용하기 위해 그 컬럼의 배열의 dtype이 선택된다.

frame3.values
#out:
#array([[nan, 1.5],
#       [2.4, 1.7],
#       [2.9, 3.6]])

frame2.values
#out:
#array([[2000, 'Ohio', 1.5, nan],
#       [2001, 'Ohio', 1.7, -1.2],
#       [2002, 'Ohio', 3.6, nan],
#       [2001, 'Nevada', 2.4, -1.5],
#       [2002, 'Nevada', 2.9, -1.7],
#       [2003, 'Nevada', 3.2, nan]], dtype=object)

 

 

5.1.3 Index 객체

표 형식의 데이터에서 각 로우와 컬럼에 대한 이름과 다른 메타데이터(축의 이름 등)을 저장하는 객체

 

괄호로 데이터 접근 가능

obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
index		#out : Index(['a', 'b', 'c'], dtype='object')
index[1:]	#out : Index(['b', 'c'], dtype='object')

 

중복되는 값을 허용하고 중복되는 값으로 선택을 하면 해당 값을 가진 모든 항목이 선택됨.

 

immutable성질을 가지므로 다음과 같은 메서드를 잘 활용해야 한다.

append : 추가 색인 객체를 덧붙여 새로운 색인 반환한다.

difference, intersection, union, isin : 색인의 차.교.합집합 반환, 색인이 넘겨받은 색인의 부분집합인지 반환

delete : i위치의 색인이 삭제된 새로운 색인 반환

drop, insert, is_monotonic, is_unique, unique 등