포스팅 목적
코드를 작성하는 연습을 하고, 어떤 코드를 썼는지 기록하는 포스팅.
특정 상황에서 문제를 해결하기 위해 어떤 코드를 작성했는지 정리하자.
문제상황
UCI-HAR 데이터셋에서 피쳐이름이 중복되어 duplicate name error가 생기는 경우가 있다.
1) 중복되는 피쳐가 무엇인지 확인하고,
2) 중복되는 피쳐이름을 리네이밍하자.
코드가 길어져 포스트 두개에 나누어 작성한다.
데이터셋
데이터 설명
UCI Human Activity Recognition Dataset을 사용한다.
https://archive.ics.uci.edu/ml/datasets/human+activity+recognition+using+smartphones
사람의 허리에 관성센서가 달린 스마트폰을 달아 하루 중 일상생활을 기록한 데이터다.
행동은
WALKING,
WALKING_UPSTAIRS,
WALKING_DOWNSTAIRS,
SITTING,
STANDING,
LAYING
이렇게 6가지가 있으며, 위 행동을 파악하기 위해 561 종류의 피쳐를 기록했다.
데이터 건수는 트레이닝 7,325건과 테스트 2,947건을 합쳐 총 10,299건이 있다.
즉 트레이닝(7352, 561)과 테스트(2947, 561)으로 나누어져 있다.
문제점
features.txt 파일을 보면, 인덱스와 피쳐이름이 찍혀있는데, 중복되는 부분이 있다.
피쳐이름'만' 중복된 것인지, 데이터까지 중복된 것인지 확인하고, 이 문제를 해결하자
문제상황 파악
우선 features.txt 파일을 읽는다.
아래와 같이 561개의 피쳐가 있다는것을 확인했다.
피쳐이름과 함께 인덱스번호도 column_index라는 이름으로 불러왔다.
import pandas as pd
# features.txt 파일에는 번호와 피쳐이름이 공백으로 분리되어 있음. 데이터프레임으로 로드.
file = './human-activity/features.txt'
features_df = pd.read_csv(file, sep='\s+', header=None, names=['column_index', 'column_name'])
# 생긴거 관찰하기
print(features_df, '\n')
print('shape: ', features_df.shape, '\n') # 561건의 피쳐종류(이름)
이번엔 중복을 확인해보자.
column_name으로 그룹바이, count()함수를 수행해보면 (477,1)이 나온다.
즉 아래 출력한대로 84개 (561-477개)만큼 중복항목이 있다는 뜻이다.
df_gb_col = features_df.groupby('column_name')
print(df_gb_col.count(), '\n')
print('타입:', type(df_gb_col.count()))
# 중복 포함해서 데이터가 477건으로 줄어들었음 -> 칼럼네임 중복이 있다는 뜻
print('중복되는 피쳐 개수:', features_df.shape[0]-df_gb_col.count().shape[0])
구체적으로 어떤 피쳐이름이 중복인지 확인해보자.
# 딕셔너리에 {키:리스트}형으로 모두 삽입한 후,
dic = {}
for idx, ser in features_df.iterrows():
try:
dic[ser[1]].append(idx)
except:
dic[ser[1]] = [idx]
# 리스트의 길이가 2이상인것만 dup에 복사한다
dup = {}
for a in dic:
if(len(dic[a])>1):
dup[a] = dic[a]
# dup 딕셔너리에는 {중복피쳐이름: 중복인덱스들}의 데이터가 남는다
dup
위와 같이 dup 딕셔너리에 중복피쳐의 이름과, 중복되는 피쳐들의 인덱스가 기록되었다.
관찰결과 중복되는 이름을 가진 피쳐가 3개씩 42개 있었다.
즉 42개의 유니크한 네임이 3개씩, 총 124개였다.
이번에는 테스트 데이터를 불러와서 실제 값까지 중복인지,
아니면 피쳐이름만 중복이었던 것인지 확인해보자.
# 테스트 데이터를 읽어와 실제 값까지 중복인지 확인해보자
file = './human-activity/test/X_test.txt'
X_test = pd.read_csv(file, sep='\s+', header=None)
# 피쳐이름을 테스트데이터 칼럼에 삽입한다.
X_test.columns = features_df.iloc[:,1]
X_test
위와 같이 (2947, 561)의 테스트 데이터를 불러왔고, 불러온 데이터프레임에 피쳐이름을 삽입했다.
중복되는 피쳐이름들을 dup에 저장해놓았기 때문에,
for문으로 중복피쳐이름을 하나씩 불러와 테스트값 데이터프레임에 넣고 평균값을 비교해본다.
# 데이터프레임 X_test에 칼럼명을 키값으로 넣어주면 해당 칼럼값이 반환된다.
for item in dup:
print(X_test[item].mean())
비교결과, 같은 피쳐이름을 가진 데이터들의 평균값이 모두 다르게 나오므로 피쳐이름만 중복되었다는걸 알 수 있다.
맺음말
피쳐이름'만' 중복이고 실제 해당하는 데이터는 모두 다르다는걸 확인했다.
다음 포스트에서는 groupby와 cumcount()를 이용해 중복되는 피쳐이름을 리네이밍해보자.
2022.11.23 - [PL/Python] - 코드 스터디: UCI-HAR 데이터셋 중복칼럼 리네이밍 (2)
'PL > Python' 카테고리의 다른 글
pandas Dataframe, Series 차이점 정리 (데이터프레임, 시리즈) (0) | 2022.10.31 |
---|---|
데이터프레임에서 for loop을 사용하는 다양한 방법 (1) | 2022.10.28 |
pandas.DataFrame.apply 함수 기본 사용법 (0) | 2022.10.27 |
pandas.DataFrame.groupby 기본 사용법 (0) | 2022.10.27 |
Pandas merge함수 사용법 기초 (0) | 2022.10.26 |
댓글