먼저, Pandas 시작 전에 pip install pandas가 필요합니다.
numpy도 사용할 것이기 때문에 pip install numpy도 필요합니다.
pandas를 이용하여 python에서 좀 더 쉽게 2차원 배열 ( 행렬 )을 생성하고 접근, 탐색, 삭제, 추가할 수 있습니다.
"""
pandas 라이브러리
1. 엑셀의 sheet, DB의 table 구조와 비슷한 DataFrame 타입으로 데이터를 관리
2. import pandas as pd
(numpy와 함께 쓰이는 경우가 대부분)
"""
dict를 이용하여 DataFrame 생성
dict의 key는 column의 label(name)이 되고 dict의 values는 column 밑에서 요소로 출력
행 index는 자동으로 0부터 column의 요소 갯수만큼 부여된다.
import pandas as pd
df = pd.DataFrame({
'a':[10,20,30], 'b':[6,3,2], 'c':[2,3,4] # dict 순서가 없다.
})
print(dir(df))
print("1. dict로 DataFrame 생성\n", df, type(df)) # <class 'pandas.core.frame.DataFrame'>
# a b c ** Column
# 0 10 6 2
# 1 20 3 3 --- 열단위 혹은 행단위의 묶음 : series
# 2 30 2 4
#Index 변경 가능
print("2.컬럼정보:", df.columns) # Index(['a', 'b', 'c'], dtype='object')
print("3.컬럼정보:", df.keys()) # Index(['a', 'b', 'c'], dtype='object')
print("4.인덱스정보:", df.index) # RangeIndex(start=0, stop=3, step=1)
print("4.값 정보:\n", df.values)
# [[10 6 2]
# [20 3 3]
# [30 2 4]]
중첩 리스트로 DataFrame 생성
중첩된 리스트들은 각자 열의 요소로 구성된다.
해당열의 label(name)은 자동으로 0부터 부여된다.
행도 자동으로 0부터 열 요소 개수만큼 부여된다.
#2. 중첩 리스트로 생성
df = pd.DataFrame([[9,8,7], [65, 44,23], [4,5,6]])
print("1. 중첩리스트로 DataFrame 생성\n", df, type(df))
# 0 1 2
# 0 9 8 7
# 1 65 44 23
# 2 4 5 6 # <class 'pandas.core.frame.DataFrame'>
따로 columns =[]로 columns label을 부여 가능
df = pd.DataFrame([[9,8,7], [65, 44,23], [4,5,6]], columns=['a', 'b', 'c'])
print("2. 중첩리스트로 생성된 DataFrame의 columns 변경:\n", df, type(df))
# a b c
# 0 9 8 7
# 1 65 44 23
# 2 4 5 6 <class 'pandas.core.frame.DataFrame'>
행의 index도 부여 가능
df = pd.DataFrame([[9,8,7], [65, 44,23], [4,5,6]], columns=['a', 'b', 'c'], index=[10, 20, 30])
print("3. 중첩리스트로 생성된 DataFrame의 columns와 index 변경\n", df, type(df))
# a b c
# 10 9 8 7
# 20 65 44 23
# 30 4 5 6 <class 'pandas.core.frame.DataFrame'>
Numpy의 arange와 reshaped를 이용하여 자동으로 DataFrame 생성 가능
columns와 index도 따로 생성 가능
df = pd.DataFrame(np.arange(15).reshape(5,3), columns=['A', 'B', 'C'], index=['r1', 'r2', 'r3', 'r4', 'r5'])
print("4. Numpy의 arnage와 reshape를 이용하여 DataFrame 생성 후 columns와 index 변경\n", df)
numpy의 랜덤값 복습
#1. 임의의 실수값 반환 : [0,1) ~~~>> 0이상 <= value < 1 미만 [이상, 이하 (포함)] (초과, 미만 (포함 x))
data = np.random.random()
print("1. 임의의 실수값 1개 반환", data)
# 0.9038239768926785
data = np.random.random(5)
print("1.임의의 실수값 5개 반환", data)
#[0.20087027 0.5384475 0.92996008 0.57920612 0.46218172]
#2. 정규분포 범위의 임의의 값 반환
data = np.random.rand(5)
print("2. 정규분보 범위의 임의의 실수값 5개 반환:", data)
# [0.29123449 0.92816889 0.66972828 0.52767369 0.97145217]
data = np.random.rand(3, 4)
print("2. 정규분보 범위의 임의의 실수값 3x4개 반환:\n", data)
# [[0.49488347 0.26196998 0.51501697 0.99176098]
# [0.52783942 0.69547549 0.70063134 0.44659846]
# [0.03705815 0.05116785 0.89310475 0.46734374]]
#3. 표준정규분포 범위의 임의의 값 반환
data = np.random.randn(5)
print("3. 표준정규분포 범위의 임의의 실수값 5개 반환:", data)
# [ 0.88706016 -1.61651442 -0.66905866 -0.48497604 1.13883641]
data = np.random.randn(3, 4)
print("3. 표준정규분포 범위의 임의의 실수값 3x4개 반환:\n", data)
# [[-0.36981021 -1.95868768 1.14315156 -1.85387642]
# [ 0.57978006 -1.24163331 0.24691548 -1.10755542]
# [-0.52393324 0.30046364 0.59125952 0.60664074]]
#4. 지정된 범위의 정수값 반환
data = np.random.randint(1,5,6) # 1~ 4범위, 갯수 6개
print("4. 정수 1 ~ 4 범위의 정수값 6개 반환 :", data)
# [1 3 3 1 1 3]
data = np.random.randint(1, 5, size=(2,4)) # 정수 1 ~ 4 범위에서 2x4 행렬 반환
print("4. 정수 1 ~ 4 범위의 2 x 4 행렬 반환\n", data)
# [[1 1 4 1]
# [3 3 2 2]]
Pandas에서 random()함수를 이용하여 DataFrame 조작하기
df = pd.DataFrame(np.random.choice(['foo', 'bar', 'kochanie', 'love'], size=(10,4)), columns=['v1','v2','v3','v4'])
print(df)
# v1 v2 v3 v4
# 0 foo kochanie bar love
# 1 bar kochanie kochanie kochanie
# 2 kochanie kochanie kochanie foo
# 3 bar love love bar
# 4 love love foo love
# 5 love foo bar foo
# 6 bar love bar kochanie
# 7 kochanie foo foo bar
# 8 bar foo kochanie kochanie
# 9 bar love kochanie bar
df = pd.DataFrame(np.random.randint(1, 4, size=(10,4)), columns=['v1','v2','v3','v4'])
print(df)
# v1 v2 v3 v4
# 0 1 2 3 2
# 1 2 1 2 2
# 2 2 2 3 1
# 3 1 2 2 1
# 4 1 2 3 3
# 5 2 3 1 1
# 6 3 3 1 1
# 7 3 2 3 2
# 8 3 1 3 3
# 9 3 3 3 2
Series 이용하여 DataFrame 생성하기
1. 개별 Series 생성
s1 = pd.Series(['유관순', '강감찬'])
print(s1, type(s1))
# 0 유관순
# 1 강감찬
# dtype: object <class 'pandas.core.series.Series'>
s2 = pd.Series([20, 43])
print(s2, type(s2))
# 0 20
# 1 43
# dtype: int64 <class 'pandas.core.series.Series'>
2. 생성된 Series를 이용해서 D
df.columns = ["사람1", "사람2"]
df.index = ["이름", "나이"]
print(df)
# 사람1 사람2
# 이름 유관순 강감찬
# 나이 20 43
ataFrame 생성
df = pd.DataFrame([s1, s2])
print(df)
# 0 1
# 0 유관순 강감찬
# 1 20 43
3. column label 과 index 조작
df.columns = ["사람1", "사람2"]
df.index = ["이름", "나이"]
print(df)
# 사람1 사람2
# 이름 유관순 강감찬
# 나이 20 43
(보기에 좋게 열과 행 뒤바꿈. Transpose (.T / .transpose() )
# new_df = df.T #Transpose
new_df = df.transpose()
print(new_df)
# 사람1 사람2
# 이름 유관순 강감찬
# 나이 20 43
통계 함수 사용하기
1. 원본 DataFrame
df = pd.DataFrame({
'a' : [4,6,7,7,5],
'b' : [6,3,2,2,55],
'c' : [2,3,4,1,2]},
index=[10, 20, 30, 40, 50])
print("1. 원본:\n", df)
# a b c
# 10 4 6 2
# 20 6 3 3
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
2. column별 최대값 ( max() default == max(axis=0) )
print("2. column별 최대값:\n", df.max())
print("2. column별 최대값:\n", df.max(axis=0))
# a 7
# b 55
# c 4
# dtype: int64
3. row별 최대값 ( max()에서 axis 값을 1로 주어 y축을 기준으로 바꿔주면 된다.)
print("3. row별 최대값:\n", df.max(axis=1))
# 10 6
# 20 6
# 30 7
# 40 7
# 50 55
# dtype: int64
4. column별 최소값
print("4. column별 최소값:\n", df.min())
print("4. column별 최소값:\n", df.min(axis=0))
# a 4
# b 2
# c 1
# dtype: int64
5. row별 최소값
print("5. row별 최소값:\n", df.min(axis=1))
# 10 2
# 20 3
# 30 2
# 40 1
# 50 2
# dtype: int64
6.column별 합계
print("6. column별 합계:\n", df.sum())
print("6. column별 합계:\n", df.sum(axis=0))
# a 29
# b 68
# c 12
# dtype: int64
7.row별 합계
print("7. row별 합계:\n", df.sum(axis=1))
# 10 12
# 20 12
# 30 13
# 40 10
# 50 62
# dtype: int64
8.column별 평균
print("8. column별 평균:\n", df.mean())
print("8. column별 평균:\n", df.mean(axis=0))
# a 5.8
# b 13.6
# c 2.4
# dtype: float64
9.row별 평균
print("9. row별 평균:\n", df.mean(axis=1))
# 10 4.000000
# 20 4.000000
# 30 4.333333
# 40 3.333333
# 50 20.666667
# dtype: float64
10.column별 중앙값
print("10. column별 중앙값:\n", df.median())
print("10. column별 중앙값:\n", df.median(axis=0))
# a 6.0
# b 3.0
# c 2.0
# dtype: float64
11.row별 중앙값
print("11. row별 중앙값:\n", df.median(axis=1))
# 10 4.0
# 20 3.0
# 30 4.0
# 40 2.0
# 50 5.0
# dtype: float64
'''
1. 편차 (deviation)
==> 평균과 데이터 값의 차
==> 모든 편차의 합은 0, 따라서 평균과 얼마나 떨어져 있는지 (분산되어 있는지) 확인이 어렵다.
이것을 해결할 수 있는 방법 ==> 분산
2. 분산 (variance)
==> 편차의 제곱의 평균
==> 제곱된 값이기 때문에 값이 매우 크다.
==> 값이 너무 크기 때문에 조절의 필요성이 있다. ==> 표준편차
3. 표준편차 (standard deviation)
==> 분산을 루트로 제곱근시킨다.
==> 데이터를 표준화 시킬 수 있다. (******) => 단위가 다른 값을 비교할 수 있다.
'''
12. column별 분산
print("12. column별 분산:\n", df.var()) #평균에서부터 얼마나 떨어져 있는가 분산의 합 = 0
print("12. column별 분산:\n", df.var(axis=0))
# a 1.7
# b 538.3
# c 1.3
# dtype: float64
13. row별 분산
print("13. row별 분산:\n", df.var(axis=1))
# 10 4.000000
# 20 3.000000
# 30 6.333333
# 40 10.333333
# 50 886.333333
# dtype: float64
14. column별 표준편차
print("14. column별 표준편차:\n", df.std()) # 분산에서 제곱해서 평균으로 나눈 것인가?
print("14. column별 표준편차:\n", df.std(axis=0))
# a 1.303840
# b 23.201293
# c 1.140175
# dtype: float64
15. row별 표준변차
print("15. row별 표준편차:\n", df.std(axis=1))
# 10 2.000000
# 20 1.732051
# 30 2.516611
# 40 3.214550
# 50 29.771351
# dtype: float64
'''
사분위범위 ( interquartile range : IQR): 3사분위 - 1사분위의 차
-사분위수 : 데이터를 동일한 비율로 4등분 할때의 3가지 분기점의 위치를 의미
1사분위수 (Q1): 25% 지정
2사분위수 (Q2): 50% 지정 (중앙값)
3사분위수 (Q3): 75% 지정
IQR = Q3 - Q1
'''
16. column별 사분위값
print("16. column별 사분위값:\n", df.quantile([0.25, 0.75]))
print("16. column별 사분위값:\n", df.quantile([0.25, 0.75], axis=0))
# a b c
# 0.25 5.0 2.0 2.0
# 0.75 7.0 6.0 3.0
17. row별 사분위값
print("17. row별 사분위값:\n", df.quantile([0.25, 0.75], axis=1))
# 10 20 30 40 50
# 0.25 3.0 3.0 3.0 1.5 3.5
# 0.75 5.0 4.5 5.5 4.5 30.0
NaN (Null) 값 조작하기
기본 DataFrame
#SQL의 NUL값 형태 ==> np.nan
df = pd.DataFrame({
'a' : [4,6,7,np.nan,5],
'b' : [6,3,2,2,np.nan], #np.nan = Null
'c' : [2,np.nan,4,1,2]},
index=[10, 20, 30, 40, 50])
print(df)
# a b c
# 10 4.0 6.0 2.0
# 20 6.0 3.0 NaN
# 30 7.0 2.0 4.0
# 40 NaN 2.0 1.0
# 50 5.0 NaN 2.0
18.coulumn별 null 제외한 값 갯수
print("18. column별 Null값 제외한 값 갯수:\n", df.count())
print("18. column별 Null값 제외한 값 갯수:\n", df.count(axis=0))
# a 4
# b 4
# c 4
# dtype: int64
19.row별 null 제외한 값 갯수
print("19. column별 Null값 제외한 값 갯수:\n", df.count(axis=1))
# 10 3
# 20 2
# 30 3
# 40 2
# 50 2
# dtype: int64
20.DataFrame의 행의 갯수 ( SQL의 count(*) )
print("20. DataFrame의 행의 갯수(SQL의 count(*)):", len(df)) #5
21.DataFrame의 열의 갯수
print("21. DataFrame의 열의 갯수(SQL의 count(*)):", len(df.columns)) #5
22. DataFrame의 scheme 제공 (SQL의 desc)
print("22. DataFrame의 기술통계 한꺼번에 제공:\n", df.describe())
# a b c
# count 4.000000 4.000000 4.000000
# mean 5.500000 3.250000 2.250000
# std 1.290994 1.892969 1.258306
# min 4.000000 2.000000 1.000000
# 25% 4.750000 2.000000 1.750000
# 50% 5.500000 2.500000 2.000000
# 75% 6.250000 3.750000 2.500000
# max 7.000000 6.000000 4.000000
23. DataFRame의 정보제공
print("23. DataFrame의 정보제공:", df.info())
# <class 'pandas.core.frame.DataFrame'>
# Int64Index: 5 entries, 10 to 50
# Data columns (total 3 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 a 4 non-null float64
# 1 b 4 non-null float64
# 2 c 4 non-null float64
# dtypes: float64(3)
# memory usage: 160.0 bytes
# 22. DataFrame의 정보제공: None
컬럼별 통계
1. 원본
df = pd.DataFrame({
'a' : [4,6,7,7,5],
'b' : [6,3,2,2,55],
'c' : [2,3,4,1,2]},
index=[10, 20, 30, 40, 50])
print("1. 원본:\n", df)
# a b c
# 10 4 6 2
# 20 6 3 3
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
2. 통계 조회
print("2. b컬럼의 최대값 조회:", df['b'].max()) #55
print("2. b컬럼과 a컬럼의 최대값 조회:\n", df[['b', 'a']].max())
# b 55
# a 7
# dtype: int64
print("3. b컬럼의 최소값 조회:", df['b'].min()) #2
print("4. b컬럼의 합계 조회:", df['b'].sum()) #68
print("5. b컬럼의 평균 조회:", df['b'].mean()) #13.6
print("6. b컬럼의 중앙값 조회:", df['b'].median()) #3.0
print("7. b컬럼의 분산 조회:", df['b'].var()) #538.3
print("8. b컬럼의 분산 조회:", df['b'].var(axis=0)) #538.3
print("9. b컬럼의 표준편차 조회:", df['b'].std()) #23.20129306741329
print("10. b컬럼의 Null값 제외한 값 갯수 조회:", df['b'].count()) #5
열(column) 검색
1.원본
df = pd.DataFrame({
'a' : [4,6,7,7,5],
'b' : [6,3,2,2,55],
'c' : [2,3,4,1,2]},
index=[10, 20, 30, 40, 50])
print("1. 원본:\n", df)
# a b c
# 10 4 6 2
# 20 6 3 3
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
2. 컬럼 조회 2가지 방법
print("2. a컬럼만 조회:\n", df.a, type(df.a))
# 10 4
# 20 6
# 30 7
# 40 7
# 50 5
# Name: a, dtype: int64 <class 'pandas.core.series.Series'>
print("2. a컬럼만 조회:\n", df['a'])
# 10 4
# 20 6
# 30 7
# 40 7
# 50 5
# Name: a, dtype: int64
3. fancy 색인으로 조회
print("3. a, b컬럼 조회(fancy색인):\n", df[['a', 'b']]) # fancy 색인 = 리스트 형태
# a b
# 10 4 6
# 20 6 3
# 30 7 2
# 40 7 2
# 50 5 55
print("3. b, a컬럼 조회(fancy색인):\n", df[['b', 'a']]) # fancy 색인 = 리스트 형태
# b a
# 10 6 4
# 20 3 6
# 30 2 7
# 40 2 7
# 50 55 5
행(row) 검색
"""
DataFrame 행 검색
1) loc 함수 : index name
==> loc[인덱스 라벨]
2) iloc 함수 : index location
==> iloc[인덱스 위치] : 0부터
"""
1. 원본
df = pd.DataFrame({
'a' : [4,6,7,7,5],
'b' : [6,3,2,2,55],
'c' : [2,3,4,1,2]},
index=[10, 20, 30, 40, 50])
print("1. 원본:\n", df)
# a b c
# 10 4 6 2
# 20 6 3 3
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
2. 인덱스 위치값으로 인덱싱 조회
print("2. 인덱스의 위치값으로 행선택(인덱싱): \n", df.iloc[0])
# a 4
# b 6
# c 2
# Name: 10, dtype: int64
3.인덱스 위치값으로 fancy 조회
print("3. 인덱스의 위치값으로 행선택(fancy): \n", df.iloc[[0,3,4]])
# a b c
# 10 4 6 2
# 40 7 2 1
# 50 5 55 2
4. 인덱스 위치값으로 (역)슬라이싱 조회
print("4. 인덱스의 위치값으로 행선택(슬라이싱): \n", df.iloc[1:3])
# a b c
# 20 6 3 3
# 30 7 2 4
print("4. 인덱스의 위치값으로 행선택(슬라이싱): \n", df.iloc[1:])
# a b c
# 20 6 3 3
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
print("4. 인덱스의 위치값으로 행선택(역슬라이싱): \n", df.iloc[::-1])
# a b c
# 50 5 55 2
# 40 7 2 1
# 30 7 2 4
# 20 6 3 3
# 10 4 6 2
5. 인덱스 라벨로 인덱싱 조회
print("5. 인덱스의 라벨로 행선택(인덱싱): \n", df.loc[10])
# a 4
# b 6
# c 2
# Name: 10, dtype: int64
6. 인덱스 라벨로 fancy 조회
print("6. 인덱스의 라벨로 행선택(fancy): \n", df.loc[[10, 30, 40]])
# a b c
# 10 4 6 2
# 30 7 2 4
# 40 7 2 1
7. 인덱스 라벨로 슬라이싱 조회
print("7. 인덱스의 라벨로 행선택(슬라이싱): \n", df.loc[30:])
# a b c
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
행열 조회
"""
DataFrame 행 검색
1) loc 함수 : index name
==> loc[인덱스 라벨]
2) iloc 함수 : index location
==> iloc[인덱스 위치] : 0부터
*행과 열 조합
df.loc[행, 열] ==> 인덱스 라벨 및 컬럼명 사용
-인덱싱, fancy, boolean, 슬라이싱 모드 가능
df.iloc[행, 열] ==> 인덱스 위치 및 컬럼 위치 사용
-인덱싱, fancy, boolean, 슬라이싱 모드 가능
.iloc requires numeric indexers, got ['a' 'b']
* loc 함수 또는 iloc 함수 사용한 색인값을 이용하여 값 변경이 가능하다.
df.loc[행, 열] = 값
df.iloc[행, 열] = 값
"""
1.원본
df = pd.DataFrame({
'a' : [4,6,7,7,5],
'b' : [6,3,2,2,55],
'c' : [2,3,4,1,2],
'd' : [12,23,64,41,28],
'e' : [25,34,42,15,52]
},
index=[10, 20, 30, 40, 50])
print("1. 원본:\n", df)
# a b c d e
# 10 4 6 2 12 25
# 20 6 3 3 23 34
# 30 7 2 4 64 42
# 40 7 2 1 41 15
# 50 5 55 2 28 52
2.모든 행 + a 열 검색 [ : , 'a'] = [ : , ['a']] (이건 fancy 색인같은데... 뭔가 이렇게 해야될 것같아서 이렇게 함.)
print("2. 모든 행에서 a열 검색(인덱싱): \n", df.loc[:, 'a'])
# 10 4
# 20 6
# 30 7
# 40 7
# 50 5
# Name: a, dtype: int64
print("2. 모든 행에서 a열 검색(인덱싱): \n", df.loc[:, 'a'])
# a b
# 10 4 6
# 20 6 3
# 30 7 2
# 40 7 2
# 50 5 55
3. 모든 행에서 a, b열 검색 (fancy) <- 이때는 fancy 색인이 아니면 Error
print("3. 모든 행에서 a, b열 검색(fancy): \n", df.loc[: , ['a', 'b']])
# c d e
# 10 2 12 25
# 20 3 23 34
# 30 4 64 42
# 40 1 41 15
# 50 2 28 52
4. 모든 행에서 c ~ e열 슬라이싱 조회
print("4. 모든 행에서 c ~ e열 검색(슬라이싱): \n", df.loc[: , 'c':'e'])
# a b
# 10 4 6
# 40 7 2
5. 10, 40 인덱스 라벨, a, b열 검색 (fancy)
print("5. 10과 40 인덱스 라벨행에서 a, b열 검색(fancy): \n", df.loc[[10, 40] , ['a', 'b']])
# a b
# 20 6 3
# 30 7 2
# 40 7 2
# 50 5 55
6.20~50 인덱스 라벨, a, b열 슬라이싱 조회
print("6. 20 ~ 50 인덱스 라벨행에서 a, b열 검색(슬라이싱): \n", df.loc[20:50 , ['a', 'b']])
# 10 False
# 20 False
# 30 False
# 40 True
# 50 False
# Name: e, dtype: bool
e컬럼의 값이 15인 행 찾기 (boolean)
print("e컬럼의 값이 15인 행 찾기:", df['e']==15)
# 10 False
# 20 False
# 30 False
# 40 True
# 50 False
# Name: e, dtype: bool
7. e 컬럼의 값이 15인 행에서 a, b 조회 ( boolean 색인 조회)
print("7. e컬럼의 값이 15인 행에서 a와 b컬럼 조회 (boolean) : \n", df.loc[ df['e'] == 15 , ['a', 'b']])
# a b
# 40 7 2
8. 2 ~ 4 인덱스, a, b 컬럼 ( fancy )
print("8. 행위치가 2 ~ 4, a와 b컬럼 조회(fancy): \n", df.iloc[ 2:5 , [0, 1]])
# a b
# 30 7 2
# 40 7 2
# 50 5 55
8. 2 ~ 4 인덱스, a ~ c 컬럼 ( 슬라이싱)
print("8. 인덱스 위치가 2 ~ 4, a ~ c컬럼(0 ~ 2) 조회(슬라이싱): \n", df.iloc[ 2:5 , :3])
# a b c
# 30 7 2 4
# 40 7 2 1
# 50 5 55 2
'SK 행복성장캠퍼스 > Pandas' 카테고리의 다른 글
20-10-07, Pandas_2일차(행렬검색, index) (0) | 2020.10.12 |
---|
댓글