728x90
#Prologue.Python을 활용한 데이터분석에 대해서 공부하면서 느낀 생각이. 
#왠지 Excel as a Code 같다는 느낌을 받는다. 
#아마 엑셀과 같은 소프트웨어프로그램은 역사속으로 사라지지 않을까 하는 생각이든다. 시각화SW도구들도 있고.
#자료구조, 알고리즘, 데이터정리, 데이터조작, 데이터분석, 데이터활용 


#판다스패키지는 Series클래스와 DataFrame클래스를 제공한다.
#DataFrame을 구성하는 각각의 칼럼이 Series클래스이다. Series의 집합이 곧 DataFrame이다.

#1.Seires클래스
#인덱스이름(라벨)을 사용할 때는 대괄호([])안에 이름과 함께 따옴표를 입력
#인덱스라벨은 문자열뿐만아니라 날짜, 시간, 정수등도 가능하다 
#인덱스를 지정하지 않고 시리즈를 만들면, 시리즈의 인덱스는 0부터 시작하는 정수값이 된다.
#(index= ??? 를 지정하지 않으면 -> 인덱싱할때 디폴트로 0부터)

#List와 tuple을 Series로 변환하는 경우, 정수형 위치 인덱스가 자동지정된다.
#시리즈의 인덱스는 index속성으로 접근할 수 있다
#시리즈의 값은 1차원 배열이며 value속성으로 접근할 수 있다
#'name속성'을 이용하여 시리즈데이터에 이름을 붙일 수 있다. 시리즈객체자체에 인듯

#작업환경은 가상환경으로 아나콘다 또는 코랩
import pandas as pd
s = pd.Series( [9904312, 3448737, 2890451, 2466052],
              index=["서울", "부산", "인천", "대구"] )
#Series클래스로부터 s클래스객체생성?
print(s)

print(pd.Series(range(10, 14)))
print(s.index) #index=["서울", "부산", "인천", "대구"] ,Index(['서울', '부산', '인천', '대구'], dtype='object')

s.name = "인구" 
print(s) #객체의 이름이 "인구"라고 나온다. 그 전엔 dtype(date type)만 나왔었다

s.index.name ="도시"
print(s) #이전과는 다르게 인덱스들에게 대한 이름이 나타난다. 인덱스들에 대한 메타데이터? 설명데이터?



  #결과
서울    9904312
부산    3448737
인천    2890451
대구    2466052
dtype: int64
0    10
1    11
2    12
3    13
dtype: int64
Index(['서울', '부산', '인천', '대구'], dtype='object')
서울    9904312
부산    3448737
인천    2890451
대구    2466052
Name: 인구, dtype: int64
도시
서울    9904312
부산    3448737
인천    2890451
대구    2466052
Name: 인구, dtype: int64


#<Series연산>
#벡터화 연산(열벡터)을 할 수 있다.
#연산은 'Series의 값'에만 적용되며 인덱스값(혹은 인덱스)은 변하지 않는다.

import pandas as pd
s = pd.Series( [9904312, 3448737, 2890451, 2466052],
              index=["서울", "부산","인천", "대구"] )
print(s/1000000)
s.name = "인구" #무언가 값에 변화를 준다는 것은 새로운입력이들어가는것. 새로운곳을바라보게하는것. 새로운값을할당해주는 것.
s.index.name = "도시"
print(s)

#결과    
서울    9.904312
부산    3.448737
인천    2.890451
대구    2.466052
dtype: float64
도시
서울    9904312
부산    3448737
인천    2890451
대구    2466052
Name: 인구, dtype: int64




#<Series인덱싱>
#배열인덱싱이나 인덱스라벨(라벨인덱싱)을 이용한 인덱싱도 가능하다. 배열인덱싱이나 라벨인덱싱도 가능하다.
#배열인덱싱이나 인덱스라벨(라벨인덱싱)을 이용한 슬라이싱도 가능하다 배열인덱싱이나 라벨인덱싱을 이용한 슬라이싱도 가능하다.
#배열인덱싱을 하면 부분적인 값을 가지는 'Series자료형'을 반환한다
#자료의 순서를 바꾸거나 특정한 자료만 선택할 수 있다
#문자열라벨을 이용한 슬라이싱을 하는 경우에는 숫자인덱싱과 달리(숫자인덱싱을 이용한 슬라이싱은 [이상, 미만]이었다)콜론(:)기호 뒤에 오는 값도 결과에 포함된다.
#라벨값이 영문문자열인 경우(국문도 되는데?)에는 인덱스라벨이 속성인 것처럼 점(.)을 이용하여 해당 인덱스값에 접근할 수도 있다.


import pandas as pd

#1차원배열
s = pd.Series([9904312, 3448737, 2890451, 2466052],
                index=["서울", "부산", "인천", "대구"]
               )
print(s,"\n###########")
print(s[1], s["부산"], "\n###########") #일반배열인덱싱(정수인덱스를 이용한 인덱싱)과 라벨인덱싱(문자열인덱스를 활용한 인덱싱)
print(s[3], s["대구"], "\n###########")
print(s[[0, 3, 1]], "\n###########") #Series객체에서도 일반배열처럼 인덱스숫자는 0부터 시작하네
#print(s[0, 3,1]) 이건 에러난다. 컴퓨터에게 인덱스키로 복수개를 제시할때에는 표기를 []안에 콤마로 연결하여 넘겨주어야 한다. 아래와 같이 문자열라벨인덱싱할때에도
print(s[["서울", "대구", "부산"]])
print(s[ (250e4 < s) & (s < 500e4) ]) #250만 초과, 500미만인 경우

s["부산":"대구"] #Series객체의 문자열인덱스(라벨인덱싱할때)로 값에 접근할때 [이상:미만]이 아니라 '["이상":"이하"]'이다
s0 = pd.Series(range(3), index=["a", "b", "c"]) #range(3) => 0, 1, 2
print(s0)
print(s0.a)
print(s0.b)

#결과
서울    9904312
부산    3448737
인천    2890451
대구    2466052
dtype: int64 
###########
3448737 3448737 
###########
2466052 2466052 
###########
서울    9904312
대구    2466052
부산    3448737
dtype: int64 
###########
서울    9904312
대구    2466052
부산    3448737
dtype: int64
부산    3448737
인천    2890451
dtype: int64
a    0
b    1
c    2
dtype: int64
0
1


#Series VS Dict
#Series = 값(value) + 인덱스(index), Series의 연산은 Series의 값에만 적용
#Series객체는 라벨값에 의해 인덱싱이 가능하므로(라벨인덱싱), 인덱스 라벨값을 키로 가지는 딕셔너리 자료형( {'key1': 'room1', 'key2':'room2'} ) 과 같다고 볼 수 있다. 
#딕셔너리 자료형에서 제공하는 in연산도 가능하고 items메서드를 사용하면 for루프를 통해 각 원소의 키와 값을 접근할 수 있다!
#딕셔너리의 원소는 순서를 가지지 않으므로(Set처럼), Series의 데이터도 순서가 보장되지 않는다.
#순서를 정하고 싶으면 인덱스를 '리스트'로 지정해야 한다. 이 리스트의 인덱스순서대로 값이 출력된다. 배열된다.

import pandas as pd

s = pd.Series([9904312, 3448737, 2890451, 2466052], index=["서울", "부산", "인천", "대구"])
print("서울" in s) # in있냐 없냐를 불리언자료형(T 또는 F)으로 반환
print("대전" in s)


print("s.items() >>>", s.items())
#zip(*iterable)은 동일한 개수로 이루어진 자료형을 묶어 주는 역할을 하는 함수이다.
"""이건 안되네
for v in s.items():
    print("%d"% k)
"""
for k, v in s.items(): #아이템 = (키, 밸류) 쌍으로 Tuple자료형으로 반환하구나
    print("%s = %d"% (k, v))

#딕셔너리자료형의 각 원소 "서울": 9631482
s2 = pd.Series( 
    {"서울": 9631482, "부산": 3393191, "인천": 2632035, "대전": 1490158} 
) 
print(s2)

s2 = pd.Series(
    {"서울": 9631482, "부산": 3393191, "인천": 2632035, "대전": 1490158},
    index = ["부산", "서울", "인천", "대전"]
)
print(s2)
print(s2.부산)
print(s2[["부산", "서울", "인천"]])
print(s2[0])
print(s2["부산"])    

#결과
True
False
s.items() >>> <zip object at 0x7fc915d8b440>
서울 = 9904312
부산 = 3448737
인천 = 2890451
대구 = 2466052
서울    9631482
부산    3393191
인천    2632035
대전    1490158
dtype: int64
부산    3393191
서울    9631482
인천    2632035
대전    1490158
dtype: int64
3393191
부산    3393191
서울    9631482
인천    2632035
대전    1490158
dtype: int64
부산    3393191
서울    9631482
인천    2632035
dtype: int64
3393191
3393191



#Series인덱싱 기반 연산
#두 Seires에 대해 연산을 하는 경우 인덱스가 같은 데이터에 대해서만 차이를 구한다
#NaN이 아닌 값을 구하려면 notnull메서드를 사용한다. 유효한것들 걸러낼때

import pandas as pd

s = pd.Series([9904312, 3448737, 2890451, 2466052], index=["서울", "부산", "인천", "대구"])
s2 = pd.Series({"서울": 9631482, "부산": 3393191, "인천": 2632035, "대전": 1490158})


ds = s - s2 
print(ds)
print(s.values - s2.values)
print(ds.notnull())
print(ds[ds.notnull()]) #결과가 True인것만 나오네
rs = (s - s2) / s2*100
print(rs)
rs = rs[rs.notnull()] #null값은 걸러내고 유효한 것만 나오게
print(rs)


#결과
대구         NaN
대전         NaN
부산     55546.0
서울    272830.0
인천    258416.0
dtype: float64
[272830  55546 258416 975894]
대구    False
대전    False
부산     True
서울     True
인천     True
dtype: bool
부산     55546.0
서울    272830.0
인천    258416.0
dtype: float64
대구         NaN
대전         NaN
부산    1.636984
서울    2.832690
인천    9.818107
dtype: float64
부산    1.636984
서울    2.832690
인천    9.818107
dtype: float64



#Series인덱싱기반 데이터추가 및 갱신
#인덱싱을 이용하면 딕셔너리처럼 데이터를 갱신(update)하거나 추가(add)할 수 있다.
#데이터를 삭제할 때도 딕셔너리처럼 del명령을 사용한다

import pandas as pd
s = pd.Series([9904312, 3448737, 2890451, 2466052], index=["서울", "부산", "인천", "대구"])
s2 = pd.Series({"서울": 9631482, "부산": 3393191, "인천": 2632035, "대전": 1490158}) # {"키": 밸류}


rs["부산"] = 1.63 #기본적으로 소수점 6자리 표현
print(rs)
rs["대구"] = 1.41
print(rs)
del rs["대구"]
print(rs)

#결과
부산    1.630000
인천    9.818107
대구    1.410000
dtype: float64
부산    1.630000
인천    9.818107
대구    1.410000
dtype: float64
부산    1.630000
인천    9.818107
dtype: float64

+ Recent posts