Python_Pandas 02

고지현·2023년 6월 24일

Python_Pandas

목록 보기
2/5
post-thumbnail

데이터프레임 고급 인덱싱

  • 인덱싱(indexing) : 데이터프레임에서 특정한 데이터만 골라내는 것
  • 라벨, 라벨 리스트, 인덱스데이터(정수) 슬라이스의 3가지 인덱싱 값을 사용하여 인덱싱
  • 그런데 Pandas는 Numpy 행렬과 같이 쉼표를 사용한 (행 인덱스, 열 인덱스) 형식의 2차원 인덱싱을 지원하기 위해 다음과 같은 특별한 인덱서(indexer) 속성도 제공
  • loc : 라벨값 기반의 2차원 인덱싱
  • iloc : 순서를 나타내는 정수 기반의 2차원 인덱싱

loc 인덱서

df.loc[행 인덱싱 값]
df.loc[행 인덱싱 값, 인덱싱 값]
  • 행 인덱싱 값 : 정수 또는 행 인덱스 데이터
  • 열 인덱싱 값 : 라벨 문자열

  • 인덱스 데이터
  • 인덱스 데이터 슬라이스
  • 인덱스 데이터 리스트
  • 같은 행 인덱스를 가지는 불리언 시리즈 (행 인덱싱의 경우)
  • 위의 값들을 반환하는 함수
df = pd.DataFrame(
    np.arange(10, 22).reshape(3, -1),
    columns = list('ABCD'),
    index = list('abc')
)
df
A	B	C	D
a	10	11	12	13
b	14	15	16	17
c	18	19	20	21

인덱싱 값을 하나만 받는 경우

  • 만약 loc 인덱서를 사용하면서 인덱스를 하나만 넣으면 행(row)을 선택
df.loc['a'], df.loc['b'], df.loc['c'] # 문자열 인덱스
# 인덱스 데이터의 슬라이스도 가능
df.loc['b':'c']
A	B	C	D
b	14	15	16	17
c	18	19	20	21
# 인덱스데이터의 리스트도 됨
df.loc[['b', 'c', 'c']]
df.loc[df.A > 15] # loc -> 불리언 배열 인덱싱, 라벨 인덱싱 모두 성립한다.
A	B	C	D
c	18	19	20	21
# 원래 (행) 인덱스값이 정수인 경우에는 슬라이싱도 라벨 슬라이싱 방식을 따르게 됨
# 즉, 슬라이스의 마지막 값이 포함
df2 = pd.DataFrame(np.arange(10, 26).reshape(4, -1),
                   columns = ['A', 'B', 'C', 'D'])
df2
A	B	C	D
0	10	11	12	13
1	14	15	16	17
2	18	19	20	21
3	22	23	24	25
# df2[1:2] 와 df2.loc[1:2] 의 차이점

# .loc 는 [n:m] n부터 m 숫자의 포함 까지의 인덱스 값
df2[1:2]
A	B	C	D
1	14	15	16	17
df2.loc[1:2]
A	B	C	D
1	14	15	16	17
2	18	19	20	21
인덱싱 값가능결과자료형추가사항
행 인덱스 값( 정수)O시리즈
행 인덱스 값 (정수) 슬라이스O데이터프레임loc가 없는 경우와 같음
행 인덱스 값 (정수) 리스트O데이터프레임
불리언 시리즈O데이터프레임시리즈의 인덱스가 데이터프레임의 행 인덱스와 같아야 함
불리언 시리즈를 반환하는 함수O데이터프레임
열 라벨Xloc가 없는 경우에만 쓸 수 있음
열 라벨 리스트Xloc가 없는 경우에만 쓸 수 있음

인덱싱 값을 행과 열 모두 받는 경우

  • df.loc[행 인덱스, 열 인덱스]와 같은 형태로 사용
df2.loc[0]['A'], df2.loc[0, "A"]
(10, 10)
# 인덱싱값으로 라벨 데이터의 슬라이싱 또는 리스트를 사용할 수도 있음
df2.loc[1:, "B"]
1    15
2    19
3    23
Name: B, dtype: int64
# 행 인덱스가 같은 불리언 시리즈나 이러한 불리언 시리즈를 반환하는 함수도 행의 인덱싱값이 될 수 있음
df2.loc[df2.A > 10, ["C"]]
C
1	16
2	20
3	24

iloc 인덱서

  • iloc 인덱서는 loc 인덱서와 달리 라벨이 아니라 순서를 나타내는 정수(integer) 인덱스만 받음 (다른 사항은 loc와 동일)
df2.iloc[0, 1]
11
df2.iloc[[2], 1:3]
	B	C
2	19	20
# loc 인덱서와 마찬가지로 인덱스가 하나만 들어가면 행을 선택
df.iloc[0]
A    10
B    11
C    12
D    13
Name: a, dtype: int64

데이터프레임에서의 데이터 조작(처리)

  • Pandas는 Numpy 2차원 배열에서 가능한 대부분의 데이터 처리
  • (+) Pandas만의 데이터 처리 및 변환 관련 함수/기능들을 제공

데이터 갯수 세기

시리즈의 갯수 세기

s = pd.Series(
    np.arange(10))
s
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: int64
s.count(), len(s)
(10, 10)

데이터 프레임의 갯수 세기

np.random.seed(621)
df = pd.DataFrame(np.random.randint(5, size=(4,4)), dtype=float)
df
0	1	2	3
0	3.0	2.0	1.0	4.0
1	0.0	1.0	2.0	3.0
2	4.0	2.0	4.0	1.0
3	0.0	0.0	0.0	0.0
df[3][2] # 3 열 인덱스 중에 2 행 인덱스의 값
1.0

범주(카테고리) 값 세기

  • 시리즈의 값이 정수, 문자열, 카테고리 값인 경우에는 value_counts 메소드로 각각의 값이 나온 횟수를 셀 수 있음
np.random.seed(23)
s2 = pd.Series(np.random.randint(6, size=100))
s2
0     3
1     0
2     1
3     0
4     5
     ..
95    3
96    1
97    0
98    3
99    2
Length: 100, dtype: int64
# 중복되지 않은 (unique) 값들만 추려내서, 각 값들의 갯수를 카운팅
s2.value_counts() # count() 와 다른 value_counts()
3    19
5    18
2    17
0    16
1    15
4    15
dtype: int64
# 행의 중복 여부
df.value_counts() # NaN 껴있으면 안 셈. 행이 조금이라도 다르면, 다른걸로 카운트 (df..)
A    B    C    D  
0.0  0.0  0.0  0.0    1
     1.0  2.0  3.0    1
3.0  2.0  1.0  4.0    1
dtype: int64
df['A'].value_counts()
0.0    2
3.0    1
4.0    1
Name: A, dtype: int64
# 고윳값 배열 # set.
df['B'].unique() # 고윳값 배열을 리턴
array([2., 1., 0.])
# 고윳값의 개수
s2.nunique()
6

정렬 (sort)

  • 데이터를 정렬하려면 sort_index 또는 sort_values
  • sort_index : 인덱스 값을 기준으로. (정수냐 라벨-문자열)
  • sort_values : 데이터 값 기준으로 정렬.

    오름차순 -> 행이 늘어나는 방향 -> 데이터 나열되는 방향으로 -> 데이터가 커지는 방향을 일치시켜주겠다 (ascending)

    내림차순 -> 데이터가 나열되는 방향 -> 데이터가 커지는 방향을 반대로 하겠다

s2.value_counts() # 값 기준으로 내림차순 -> descending
3    19
5    18
2    17
0    16
1    15
4    15
dtype: int64
s2.value_counts(ascending=True)
1    15
4    15
0    16
2    17
5    18
3    19
dtype: int64
# s2.value_counts().sort_index(ascending=True)
s2.value_counts().sort_index() # 인덱스를 기준으로 오름차순
0    16
1    15
2    17
3    19
4    15
5    18
dtype: int64
s2.value_counts().sort_index(ascending=False) # 인덱스 기준으로 내림차순
5    18
4    15
3    19
2    17
1    15
0    16
dtype: int64
s.sort_values() # NaN은 가장 밑으로 내려가게 처리한다
0    0.0
1    1.0
2    2.0
4    4.0
5    5.0
6    6.0
7    7.0
8    8.0
9    9.0
3    NaN
dtype: float64
s.sort_values(na_position='last') #na_position 으로 NaN 마지막 위치 설정
0    0.0
1    1.0
2    2.0
4    4.0
5    5.0
6    6.0
7    7.0
8    8.0
9    9.0
3    NaN
dtype: float64
s.sort_values(na_position='first') #na_position 으로 NaN 첫번째 위치 설정
3    NaN
0    0.0
1    1.0
2    2.0
4    4.0
5    5.0
6    6.0
7    7.0
8    8.0
9    9.0
dtype: float64
# 데이터 프레임의 경우에는 sort_values 하고 싶으면 기준이 되는 열의 라벨(이름)을 by로 지정해야한다
df.sort_values(by='A')
A	B	C	D
1	0.0	1.0	2.0	3.0
3	0.0	0.0	0.0	0.0
0	3.0	2.0	1.0	4.0
2	4.0	2.0	4.0	NaN
df.sort_values(by=['B', 'A', 'D'], na_position='first')
A	B	C	D
3	0.0	0.0	0.0	0.0
1	0.0	1.0	2.0	3.0
0	3.0	2.0	1.0	4.0
2	4.0	2.0	4.0	NaN

apply 변환

  • sum, mean 이미 정의된 함수/메소드. 어떠한 작업을 해줄지 이미 정해져있음
  • 행이나 열 단위로 복잡한 데이터 처리 -> apply 메소드 사용
  • 인수로 행 또는 열을 받는 함수 (axis)를 apply 메소드의 인수로 넣으면 각 열(또는 행)을 반복하여 그 함수에 적용시킴
df4 = pd.DataFrame({
    'A': [1, 3, 4, 3, 4],
    'B': [2, 3, 1, 2, 3],
    'C': [1, 5, 2, 4, 4],
})
df4
A	B	C
0	1	2	1
1	3	3	5
2	4	1	2
3	3	2	4
4	4	3	4
# 각 열의 최댓값과 최솟값의 차이를 구하는 연산
df4.max() - df4.min()
A    3
B    2
C    4
dtype: int64
# 람다 함수
lambda x: (x) # lambda 인자들 :인자를 사용해서 반환될 표현식
# 익명함수 -> lambda 이름을 줄 필요 X (def ... 변수에 할당) -> 사용되고 휘발
# x -> 처리할 데이터 -> apply 변수
# df3.apply(lambda x: x.max() - x.min())
df4.apply(lambda x: x.max() - x.min(), axis=0)
A    3
B    2
C    4
dtype: int64

astype 메소드

  • 지정한 시리즈, 데이터프레임의 자료형을 변경
df4.apply(pd.value_counts).fillna(0.0)
df4
	A	B	C
0	1	2	1
1	3	3	5
2	4	1	2
3	3	2	4
4	4	3	4

실수 값을 범주형 값으로 변환

  • 연령 (숫자) -> 0~99 -> 어린이, 청소년, 청년, 중년, 노년...
  • 소득 (숫자) -> 빈민, 서민, 중산, 부유, 초부유층...

    실수 값을 크기 기준으로 하여 카테고리 값으로 변환하고 싶을 때 cut qcut

데이터프레임 인덱스 조작

  • set_index : 특정한 열을 새로운 행 인덱스로 지정 (기존 행의 인덱스를 제거)
  • reset_index : 기존의 행 인덱스를 제거하고, 해당 인덱스를 새로운 열로 추가
arr = np.vstack([
    list('ABCDE'),
    np.round(np.random.rand(3, 5), 2)
])
arr
array([['A', 'B', 'C', 'D', 'E'],
       ['0.11', '0.82', '0.31', '0.26', '0.41'],
       ['0.55', '0.63', '0.08', '0.97', '0.41'],
       ['0.72', '0.66', '0.22', '0.19', '0.73']], dtype='<U32')
df2 = df1.set_index('C1')
df2
       C2	  C3	  C4
C1			
A	0.11	0.55	0.72
B	0.82	0.63	0.66
C	0.31	0.08	0.22
D	0.26	0.97	0.19
E	0.41	0.41	0.73
df2.reset_index(drop=True)
      C2	  C3	  C4
0	0.11	0.55	0.72
1	0.82	0.63	0.66
2	0.31	0.08	0.22
3	0.26	0.97	0.19
4	0.41	0.41	0.73

데이터프레임에서의 삭제 drop

# del 로 키값을 지정해서 지울 수 있다
# -> 일반적으로 쓰이는 방식은 아니다
# df.drop 메소드
df3
0	1	2	3	4	5	6	7	   Sum	Average	Std
0	7	9	6	7	1	3	4	4	41	9.11	10.94
1	6	5	0	6	1	5	7	5	35	7.78	9.39
2	8	2	3	1	0	7	1	0	22	4.89	6.32
3	0	1	8	1	2	1	0	1	14	3.11	4.27

0개의 댓글