defaultdict와 딕셔너리 응용 코드
"밑바닥부터 시작하는 데이터 과학"의 챕터 1에서 발췌 및 수정.
이해하기 쉬운 문제들 일부 추출하고, 일부는 새롭게 구성.
구글에서 "id": 0, "name": "Hero" 검색하면 소스코드로 바로 이동할 수 있다.
아래 코드는 뒤에서 제안할 문제에서 사용하는 데이터 정의.
이번 코드를 통해 dict 클래스 확장판인 defaultdict 클래스에 대해 알게 되면 좋겠다.
users = [
{ "id": 0, "name": "Hero" },
{ "id": 1, "name": "Dunn" },
{ "id": 2, "name": "Sue" },
{ "id": 3, "name": "Chi" },
{ "id": 4, "name": "Thor" },
{ "id": 5, "name": "Clive" },
{ "id": 6, "name": "Hicks" },
{ "id": 7, "name": "Devin" },
{ "id": 8, "name": "Kate" },
{ "id": 9, "name": "Klein" },
{ "id": 10, "name": "Jen" }
]
friendships = [(0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (3, 4),
(4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]
interests = [
(0, "Hadoop"), (0, "Big Data"), (0, "HBase"), (0, "Java"),
(0, "Spark"), (0, "Storm"), (0, "Cassandra"),
(1, "NoSQL"), (1, "MongoDB"), (1, "Cassandra"), (1, "HBase"),
(1, "Postgres"), (2, "Python"), (2, "scikit-learn"), (2, "scipy"),
(2, "numpy"), (2, "statsmodels"), (2, "pandas"), (3, "R"), (3, "Python"),
(3, "statistics"), (3, "regression"), (3, "probability"),
(4, "machine learning"), (4, "regression"), (4, "decision trees"),
(4, "libsvm"), (5, "Python"), (5, "R"), (5, "Java"), (5, "C++"),
(5, "Haskell"), (5, "programming languages"), (6, "statistics"),
(6, "probability"), (6, "mathematics"), (6, "theory"),
(7, "machine learning"), (7, "scikit-learn"), (7, "Mahout"),
(7, "neural networks"), (8, "neural networks"), (8, "deep learning"),
(8, "Big Data"), (8, "artificial intelligence"), (9, "Hadoop"),
(9, "Java"), (9, "MapReduce"), (9, "Big Data")
]
# 근속연수에 대한 연봉 : 사용하지 않는 데이터
salaries_and_tenures = [(83000, 8.7), (88000, 8.1),
(48000, 0.7), (76000, 6),
(69000, 6.5), (76000, 7.5),
(60000, 2.5), (83000, 10),
(48000, 1.9), (63000, 4.2)]
[문제 1번] users에 각각의 회원들에 대한 친구 필드를 추가하세요.
from collections import defaultdict
def find_member(users, member_id):
for u in users:
if u['id'] == member_id:
return u
return None
for u in users:
u['friend'] = []
# for i, j in friendships: # id가 순서를 보장할 수 없다면,
# u1 = find_member(users, i)
# u2 = find_member(users, j)
#
# u1['friend'].append(j)
# u2['friend'].append(i)
for i, j in friendships: # id가 순서를 보장한다면,
users[i]['friend'].append(j)
users[j]['friend'].append(i)
print(*users, sep='\n')
print('-'*50)
# [출력 결과]
# {'friend': [1, 2], 'id': 0, 'name': 'Hero'}
# {'friend': [0, 2, 3], 'id': 1, 'name': 'Dunn'}
# {'friend': [0, 1, 3], 'id': 2, 'name': 'Sue'}
# {'friend': [1, 2, 4], 'id': 3, 'name': 'Chi'}
# {'friend': [3, 5], 'id': 4, 'name': 'Thor'}
# {'friend': [4, 6, 7], 'id': 5, 'name': 'Clive'}
# {'friend': [5, 8], 'id': 6, 'name': 'Hicks'}
# {'friend': [5, 8], 'id': 7, 'name': 'Devin'}
# {'friend': [6, 7, 9], 'id': 8, 'name': 'Kate'}
# {'friend': [8], 'id': 9, 'name': 'Klein'}
# {'friend': [], 'id': 10, 'name': 'Jen'}
[문제 2] 친구가 가장 많은 사람과 적은 사람을 출력하세요.
users_by_friends = sorted(users, key=lambda d: len(d['friend']), reverse=True)
print(users[0])
print(users[-1])
print('.'*50)
print(*users_by_friends, sep='\n')
print('-'*50)
# [출력 결과]
# {'friend': [1, 2], 'id': 0, 'name': 'Hero'}
# {'friend': [], 'id': 10, 'name': 'Jen'}
# ..................................................
# {'friend': [0, 2, 3], 'id': 1, 'name': 'Dunn'}
# {'friend': [0, 1, 3], 'id': 2, 'name': 'Sue'}
# {'friend': [1, 2, 4], 'id': 3, 'name': 'Chi'}
# {'friend': [4, 6, 7], 'id': 5, 'name': 'Clive'}
# {'friend': [6, 7, 9], 'id': 8, 'name': 'Kate'}
# {'friend': [1, 2], 'id': 0, 'name': 'Hero'}
# {'friend': [3, 5], 'id': 4, 'name': 'Thor'}
# {'friend': [5, 8], 'id': 6, 'name': 'Hicks'}
# {'friend': [5, 8], 'id': 7, 'name': 'Devin'}
# {'friend': [8], 'id': 9, 'name': 'Klein'}
# {'friend': [], 'id': 10, 'name': 'Jen'}
[문제 3] 친구가 한 명도 없는 사람들을 출력하세요.
no_friend = [d for d in users if not d['friend']]
print(*no_friend, sep='\n')
print('-'*50)
# [출력 결과]
# {'friend': [], 'id': 10, 'name': 'Jen'}
[문제 4] 친구가 3명 이상인 사람들을 출력하세요.
more_3 = [d for d in users if len(d['friend']) >= 3]
print(*more_3, sep='\n')
print('-'*50)
# [출력 결과]
# {'friend': [0, 2, 3], 'id': 1, 'name': 'Dunn'}
# {'friend': [0, 1, 3], 'id': 2, 'name': 'Sue'}
# {'friend': [1, 2, 4], 'id': 3, 'name': 'Chi'}
# {'friend': [4, 6, 7], 'id': 5, 'name': 'Clive'}
# {'friend': [6, 7, 9], 'id': 8, 'name': 'Kate'}
[문제 5] 회원이 관심 갖는 주제들을 출력하세요.
def find_interest_by_member(interests, member_id):
finds = []
for m_id, interest in interests:
if m_id == member_id:
finds.append(interest)
return finds
print(find_interest_by_member(interests, 1))
users_by_member = defaultdict(list)
for m_id, interest in interests:
users_by_member[m_id].append(interest)
# print(*users_by_member.items(), sep='\n')
print(users_by_member[1])
print('-'*50)
# [출력 결과]
# ['NoSQL', 'MongoDB', 'Cassandra', 'HBase', 'Postgres']
# ['NoSQL', 'MongoDB', 'Cassandra', 'HBase', 'Postgres']
[문제 6] hadoop에 관심 있는 사람들을 출력하세요.
def find_members_by_interest(interests, word):
finds = []
for m_id, interest in interests:
if interest == word:
finds.append(m_id)
return finds
print(find_members_by_interest(interests, 'Hadoop'))
interest_users = defaultdict(list)
for m_id, interest in interests:
interest_users[interest].append(m_id)
# print(*interest_users.items(), sep='\n')
print(interest_users['Hadoop'])
print('-'*50)
# [출력 결과]
# [0, 9]
# [0, 9]
[문제 7] 가장 많은 관심을 갖는 주제 3가지를 출력하세요.
from collections import Counter
from operator import itemgetter
c = defaultdict(int)
for _, word in interests:
c[word] += 1
# c = Counter([word for _, word in interests])
c = sorted(c.items(), key=itemgetter(1))
print(c[:-4:-1])
print(c[::-1])
# [출력 결과]
# [('Python', 3), ('Java', 3), ('Big Data', 3)]
# [('Python', 3), ('Java', 3), ('Big Data', 3), ('R', 2), <이하 생략>
'파이썬' 카테고리의 다른 글
enum 클래스 (0) | 2017.04.09 |
---|---|
구조체로 사용할 수 있는 collections.namedtuple (0) | 2017.04.09 |
defaultdict 사용법 (0) | 2017.04.06 |
정규분포와 누적분포 비교 그래프 (0) | 2017.04.06 |
matplotlib colormap (0) | 2017.04.05 |