수월한 인덱싱을 위해 특정 데이터를 따로 추출하는 선행 작업이 필터링이다. 특정 날짜 기간에 해당하는 데이터를 불러온다던지, 특정 키워드와 연관된 데이터를 가져오려면 단순 인덱싱만으로는 힘들 것이다. 이럴 때 필터링 과정을 통해 더욱 수월하게 데이터 인덱스를 추출할 수 있다.
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 74485 entries, 0 to 74484
Data columns (total 29 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 사고번호 74485 non-null object
1 사고년도 74485 non-null int64
2 사고월 74485 non-null int64
3 사고일 74485 non-null int64
4 사고시각 74485 non-null int64
5 사고요일 74485 non-null int64
6 시군구_대범주 74485 non-null object
7 시군구_소범주 74485 non-null object
8 사고내용 74485 non-null object
9 사망자수 74485 non-null int64
10 중상자수 74485 non-null int64
11 경상자수 74485 non-null int64
12 부상신고자수 74485 non-null int64
13 사고유형_대범주 74485 non-null object
14 사고유형_소범주 74485 non-null object
15 법규위반 74485 non-null object
16 노면상태_대범주 74485 non-null object
17 노면상태_소범주 74485 non-null object
18 기상상태 73575 non-null object
19 도로형태_대범주 74485 non-null object
...
27 피해운전자연령 72049 non-null float64
28 피해운전자상해정도 72225 non-null object
dtypes: float64(2), int64(9), object(18)
memory usage: 16.5+ MB
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...
Boolean Series
특정 컬럼을 조건부로 조회하면 해당 조건이 참인 인덱스는 True, 거짓인 인덱스는 False를 반환한다. 이 때 아래와 같이 새로운 컬럼을 선언하면서 조건부를 선언하면 해당 컬럼명에 Boolean 값을 삽입할 수 있다.
# 2020년도 여부
df['Y2020'] = df['사고년도']==2020
# 사고요일이 주말?
df['사고요일']>=5
(df['사고요일']>=5).sum()
18545
# 법규위반이 중앙선침범?
df['법규위반'] == '중앙선침범'
0 False
1 False
2 False
3 False
4 False
...
74480 False
74481 True
74482 False
74483 False
74484 False
Name: 법규위반, Length: 74485, dtype: bool
한번에 여러 조건을 적용하고 싶을 때는 아래와 같이 변수에 조건절을 담아주고 해당 변수를 조건연산자로 묶어주면 된다.
# 주말이고 기상상태가 맑음?
c1 = df['사고요일']>=5
c2 = df['기상상태'] == '맑음'
(c1 & c2).mean()
0.21841981607034974
# 중상자수가 5명이상이거나 사망자수가 1명이상?
c1 = df['중상자수']>=5
c2 = df['사망자수']>=1
(c1 | c2).sum()
485
# 2019년도의 강남구?
c1 = ~df['Y2020']
c2 = df['시군구_대범주'] == '강남구'
(c1 & c2).sum()
3722
# 강남구와 성북구의 2019년도?
c1 = df['시군구_대범주'] == '강남구'
c2 = df['시군구_대범주'] == '성북구'
((c1 | c2) & (~df['Y2020'])).sum()
or
my_region = ['강남구','성북구']
c1 = (df['시군구_대범주'].isin(my_region))
(c1 &(~df['Y2020'])).sum()
5231
# 가해운전자연령이 20대?
c1 = df['가해운전자연령']>=20
c2 = df['가해운전자연령']<=29
(c1 & c2).sum()
or
df['가해운전자연령'].between(20,29).sum()
9262
필터링 사례
# 강남구와 성북구의 2019년도 사고만 필터링
my_region = ['강남구','성북구']
c = (df['시군구_대범주'].isin(my_region))
c = (c & (~df['Y2020']))
#df[c]
df.loc[c]
사고번호 사고년도 사고월 사고일 사고시각 사고요일 시군구_대범주 시군구_소범주 사고내용 사망자수 ... 도로형태_소범주 가해운전자차종 가해운전자성별 가해운전자연령 가해운전자상해정도 피해운전자차종 피해운전자성별 피해운전자연령 피해운전자상해정도 Y2020
8 A2019010100100041 2019 1 1 2 1 강남구 강남구 삼성동 경상사고 0 ... 교차로 - 교차로안 승용 여 28.0 상해없음 승용 남 59.0 경상 False
9 A2019010100100042 2019 1 1 2 1 강남구 강남구 논현동 경상사고 0 ... 단일로 - 기타 승용 여 30.0 상해없음 보행자 남 47.0 경상 False
18 A2019010100100075 2019 1 1 5 1 강남구 강남구 역삼동 경상사고 0 ... 교차로 - 교차로부근 승용 남 27.0 NaN 승용 남 45.0 경상 False
22 A2019010100100087 2019 1 1 6 1 강남구 강남구 도곡동 경상사고 0 ... 단일로 - 기타 승용 남 73.0 경상 승용 남 39.0 경상 False
24 A2019010100100099 2019 1 1 7 1 강남구 강남구 압구정동 중상사고 0 ... 기타 - 기타 승용 남 20.0 상해없음 승용 남 51.0 상해없음 False
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
39243 A2019123100100548 2019 12 31 20 1 강남구 강남구 압구정동 경상사고 0 ... 단일로 - 기타 승용 남 67.0 상해없음 승용 여 40.0 경상 False
39248 A2019123100100585 2019 12 31 21 1 강남구 강남구 개포동 경상사고 0 ... 교차로 - 교차로횡단보도내 이륜 남 37.0 상해없음 자전거 남 45.0 경상 False
39254 A2019123100100611 2019 12 31 22 1 강남구 강남구 삼성동 경상사고 0 ... 단일로 - 기타 승용 여 41.0 상해없음 승용 여 61.0 경상 False
39256 A2019123100100634 2019 12 31 23 1 강남구 강남구 역삼동 부상신고사고 0 ... 단일로 - 기타 승용 남 59.0 상해없음 NaN NaN NaN NaN False
39257 A2019123100100635 2019 12 31 23 1 강남구 강남구 수서동 경상사고 0 ... 교차로 - 교차로안 승용 남 50.0 상해없음 승용 남 53.0 경상 False
5231 rows × 30 columns
# 강남구와 성북구의 2019년도 사고의 부상신고자수
my_region = ['강남구','성북구']
my_col = ['부상신고자수']
c = (df['시군구_대범주'].isin(my_region))
c = (c & (~df['Y2020']))
df.loc[c, my_col]
부상신고자수
8 0
9 0
18 0
22 0
24 0
... ...
39243 0
39248 0
39254 0
39256 2
39257 0
5231 rows × 1 columns
# 가해운전자연령이 20대인 사고의 수치 요약
df[df['가해운전자연령'].between(20,29)].describe().T
or
qur = "20<=가해운전자연령<=29"
df.query(qur).describe().T
count mean std min 25% 50% 75% max
사고년도 9262.0 2019.498596 0.500025 2019.0 2019.0 2019.0 2020.0 2020.0
사고월 9262.0 6.606133 3.355597 1.0 4.0 7.0 10.0 12.0
사고일 9262.0 15.983589 8.747422 1.0 8.0 16.0 23.0 31.0
사고시각 9262.0 13.444828 6.792951 0.0 9.0 15.0 19.0 23.0
사고요일 9262.0 3.093284 1.971983 0.0 1.0 3.0 5.0 6.0
사망자수 9262.0 0.005938 0.076835 0.0 0.0 0.0 0.0 1.0
중상자수 9262.0 0.256856 0.494210 0.0 0.0 0.0 0.0 6.0
경상자수 9262.0 1.010905 0.985035 0.0 0.0 1.0 1.0 27.0
부상신고자수 9262.0 0.137119 0.395124 0.0 0.0 0.0 0.0 7.0
가해운전자연령 9262.0 25.431116 2.646823 20.0 23.0 26.0 28.0 29.0
피해운전자연령 8983.0 45.433819 15.936191 2.0 32.0 46.0 58.0 91.0
위 코드처럼 query() 함수를 조건연산자 대신해서 사용할 수 있지만, query() 함수의 경우 인자를 조건절로 변환하는 과정이 꽤 오래걸려서 그다지 추천하는 방식은 아니다.
# 가해운전자연령이 80대이상 사고의 수치 요약
df[df['가해운전자연령']>=80].describe().T
or
qur = "80<=가해운전자연령"
df.query(qur).describe().T
count mean std min 25% 50% 75% max
사고년도 558.0 2019.465950 0.499287 2019.0 2019.0 2019.0 2020.00 2020.0
사고월 558.0 6.672043 3.361249 1.0 4.0 7.0 10.00 12.0
사고일 558.0 15.754480 8.660706 1.0 9.0 16.0 23.00 31.0
사고시각 558.0 12.801075 4.231395 0.0 10.0 13.0 16.00 23.0
사고요일 558.0 2.741935 1.903808 0.0 1.0 3.0 4.00 6.0
사망자수 558.0 0.016129 0.126085 0.0 0.0 0.0 0.00 1.0
중상자수 558.0 0.268817 0.518383 0.0 0.0 0.0 0.75 6.0
경상자수 558.0 0.862007 0.970271 0.0 0.0 1.0 1.00 10.0
부상신고자수 558.0 0.150538 0.377450 0.0 0.0 0.0 0.00 2.0
가해운전자연령 558.0 82.611111 2.807598 80.0 81.0 82.0 84.00 98.0
피해운전자연령 541.0 47.696858 15.455688 8.0 37.0 49.0 59.00 87.0
'빅데이터분석👨💻' 카테고리의 다른 글
[Python] 빅데이터 분석 기초 - 객체 병합 함수 (concat, join, merge) (0) | 2023.12.18 |
---|---|
[Python] 빅데이터 분석 기초 - 집계 (Aggregation) (0) | 2023.11.27 |
[Python] 빅데이터 분석 기초 - 인덱싱 (Indexing) (0) | 2023.11.27 |
[Python] 빅데이터 분석 기초 - 이상치 처리 (Check the Outlier) (0) | 2023.11.24 |
[Python] 빅데이터 분석 기초 - 결측치 처리 (Missing Data Handling) (0) | 2023.11.24 |