00 개요
- 리스트를 다루는 도중 리스트 안에 중복된 값이 존재할 때, 중복되지 않는 값들만 담은 리스트를 생성하는 방법에 대한 정리
- 크게 두 분류로, 본래 리스트 안의 중복되지 않는 값들의 순서 보존 여부로 나뉨
순서 보존 안 됨 |
순서 보존됨 |
- set() 사용
- pandas 라이브러리의 Series 객체의 value_counts 사용
- itertools 라이브러리의 groupby 사용
|
- dict.fromkeys() 사용
- loop 사용
- list comprehension 사용
- pandas 라이브러리의 unique() 사용
- pandas 라이브러리의 Series 객체의 drop_duplicates 사용
|
- 언제 어떤 사용법을 적용해야 할까?
- 순서를 지켜야할 경우: dict.fromkeys(), loop, list comprehension 등 사용
- 순서를 안 지켜도 되는 경우: set() 사용
- 데이터셋이 클 경우: 성능을 위해 set() 또는 pandas.unique() 사용
01 사용 방법
1. set() 사용
- 가장 간단한 방법
- 원래 list를 set으로 변환시킨 다음 다시 list로 변환하는 방법
- 원래 순서가 보존되지 않음
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
set_unique = set(original_list)
set_unique_list = list(set(original_list))
print('set_unique:', set_unique)
print('type:', (type(set_unique)))
print('set_unique_list:',set_unique_list)
# set_unique: {0, 1, 2, 3, 4, 6} (순서 보존 안 됨)
# type: <class 'set'>
# set_unique_list: [0, 1, 2, 3, 4, 6] (순서 보존 안 됨)
2. dict.fromkeys() 사용
- Python3.7 버전부터 dictionary 객체는 주입 순서 (insertion order)를 보존함
- dict.fromkeys() 메소드를 사용하여 중복된 값 제거하는 동시 원래 순서도 보존됨
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
dict_unique = dict.fromkeys(original_list)
dict_unique_list = list(dict.fromkeys(original_list))
print('dict_unique:', dict_unique)
print('type:', (type(dict_unique)))
print('dict_unique_list:',dict_unique_list)
# dict_unique: {0: None, 2: None, 1: None, 4: None, 6: None, 3: None}
# type: <class 'dict'>
# dict_unique_list: [0, 2, 1, 4, 6, 3]
3. Loop 사용
- 수동적으로 원래 리스트를 반복하며 고유한 값들만 새 리스트에 추가하는 방법
- 원래 순서 보존됨
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
loop_list = list()
for i in range(len(original_list)):
if original_list[i] not in loop_list:
loop_list.append(original_list[i])
print('loop_list:', loop_list)
# loop_list: [0, 2, 1, 4, 6, 3]
4. List Comprehension 사용
- for loop를 더 간결하게 사용하는 방법
- 원래 순서 보존됨
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
list_comp_list = []
[list_comp_list.append(val) for val in original_list if val not in list_comp_list]
print('list_comp_list:', list_comp_list)
# list_comp_list: [0, 2, 1, 4, 6, 3]
5. pandas의 unique() 사용
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
import pandas
pd_unique = pandas.unique(original_list)
pd_unique_list = pd_unique.tolist() # 또는 list(pd_unique)
print('pd_unique:', pd_unique)
print('type:', (type(pd_unique)))
print('pd_unique_list:',pd_unique_list)
# pd_unique: [0 2 1 4 6 3]
# type: <class 'numpy.ndarray'>
# pd_unique_list: [0, 2, 1, 4, 6, 3]
6. pandas의 Series 객체 사용
1) Series 객체의 drop_duplicates() 사용
- pandas.Series에서 중복된 값을 제거하는 메서드
- 원래 순서 보존됨
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
import pandas
series = pandas.Series(original_list)
series_unique = series.drop_duplicates()
series_unique_list = series_unique.tolist()
print('series:', series)
print('type:', (type(series)))
print('series_unique:', series_unique)
print('type:', (type(series_unique)))
print('series_unique_list:',series_unique_list)
# series: 0 0
# 1 2
# 2 1
# 3 4
# 4 4
# 5 2
# 6 6
# 7 3
# 8 2
# 9 3
# dtype: int64
# type: <class 'pandas.core.series.Series'>
# series_unique: 0 0
# 1 2
# 2 1
# 3 4
# 6 6
# 7 3
# dtype: int64
# type: <class 'pandas.core.series.Series'>
# series_unique_list: [0, 2, 1, 4, 6, 3]
2) Series 객체의 value_counts() 사용
- pandas.Series에서 각 값의 개수를 추출하여, 그들의 고유값을 추출하는 방법
- 원래 순서가 보존되지 않음
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
import pandas
series = pandas.Series(original_list)
series_val_cnts = series.value_counts() # 개수가 가장 많은 순으로 정렬됨
series_val_cnts_idx = series_val_cnts.index
print('series:', series)
print('type:', (type(series)))
print('series_val_cnts:', series_val_cnts)
print('type:', (type(series_val_cnts)))
print('series_val_cnts_idx:',series_val_cnts_idx)
print('type:', (type(series_val_cnts)))
# series: 0 0
# 1 2
# 2 1
# 3 4
# 4 4
# 5 2
# 6 6
# 7 3
# 8 2
# 9 3
# dtype: int64
# type: <class 'pandas.core.series.Series'>
# series_val_cnts: 2 3
# 4 2
# 3 2
# 0 1
# 1 1
# 6 1
# Name: count, dtype: int64
# type: <class 'pandas.core.series.Series'>
# series_val_cnts_idx: Index([2, 4, 3, 0, 1, 6], dtype='int64')
# type: <class 'pandas.core.series.Series'>
# series_val_cnts_idx_list: [2, 4, 3, 0, 1, 6]
7. itertools의 groupby 메소드 사용
- 성능을 위해 itertools를 사용하여 hashable 객체를 포함한 리스트 안에 있는 중복값들 제거 가능
- groupby 메소드는 연속된 중복값만 제거하기 때문에 사용하기 전에 원래 리스트를 정렬해줘야 됨
- 그러므로 원래 순서 보존 안 됨
original_list = [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
print('original:', original_list)
# original: [0, 2, 1, 4, 4, 2, 6, 3, 2, 3]
from itertools import groupby
# 원래 리스트 정렬 안 할 경우
gb_list = [key for key, _ in groupby(original_list)]
print('gb_list:', gb_list)
# gb_list: [0, 2, 1, 4, 2, 6, 3, 2, 3] # 연속된 숫자 4만 중복값 제거됨, 나머지는 그대로 유지
# 원래 리스트 정렬 한 경우
gb_unique_list = [key for key, _ in groupby(sorted(original_list))]
print('gb_unique_list:', gb_unique_list)
# gb_unique_list: [0, 1, 2, 3, 4, 6] # 중복값 제거됨, 그러나 순서 보존 안 됨