numbers = list(range(3, 14))
numbers
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
pd.Series(numbers)
0 3
1 4
2 5
3 6
4 7
5 8
6 9
7 10
8 11
9 12
10 13
dtype: int64
letters = list('programmers')
pd.Series(letters)
0 p
1 r
2 o
3 g
4 r
5 a
6 m
7 m
8 e
9 r
10 s
dtype: object
letters_index = {f"문자{i}" for i in range(1, 12)}
letters_index
pd.Series(letters, index=letters_index)
문자7 p
문자11 r
문자1 o
문자2 g
문자9 r
문자6 a
문자10 m
문자8 m
문자3 e
문자5 r
문자4 s
dtype: object
# Dict -> Series
user = {
"name": "Spencer",
"age": 20,
"job": None
}
# key->index, value->value
pd.Series(user)
name Spencer
age 20
job None
dtype: object
# Dict->Series 할 때 index를 지정하면
pd.Series(user, index=['name', 'age', 'address'])
name Spencer
age 20
address NaN
dtype: object
numbers = list(range(1, 7))
letters = list("spencer")
numbers, letters
([1, 2, 3, 4, 5, 6], ['s', 'p', 'e', 'n', 'c', 'e', 'r'])
number_series = pd.Series(numbers)
letters_series = pd.Series(letters)
# dtype : 시리즈가 반환하는(담고있는) 데이터 타입
number_series.dtype
letters_series.dtype # O는 object라는 의미
dtype('int64')
dtype('O')
number_series.index
letters_series.index
RangeIndex(start=0, stop=6, step=1)
RangeIndex(start=0, stop=7, step=1)
# 각각의 데이터의 유형이 다 같아야함
number_series.values
letters_series.values
array([1, 2, 3, 4, 5, 6], dtype=int64)
array(['s', 'p', 'e', 'n', 'c', 'e', 'r'], dtype=object)
number_series.shape
letters_series.shape
(6,)
(7,)
number_series.size
letters_series.size
6
7
number_series.hasnans
letters_series.hasnans
False
False
scores = [90.5, 55.5, 81.4, None, 75.6]
scores_series = pd.Series(scores)
scores_series.max()
90.5
scores_series.idxmax()
0
scores_series.min()
55.5
scores_series.idxmin()
1
scores_series.sum()
303.0
scores_series.mean()
75.75
scores_series.isnull()
scores_series.isna()
0 False
1 False
2 False
3 True
4 False
dtype: bool
scores_series.round()
0 90.0
1 56.0
2 81.0
3 NaN
4 76.0
dtype: float64
round(4.5)
round(5.5)
4
6
초등학교, 중학교 수학에서 반올림은 이 경우 '올림'으로 처리합니다.
0, 1, 2, 3, 4 는 내림(버리고)
5, 6, 7, 8, 9 는 올리고
다만 이 때 통계적으로 '중립성'이 깨지게 됩니다. 예를 들어볼까요?
0.5 + 1.5 + 2.5 + 3.5 = 8.5 입니다. 그런데 각 항목에 위치하는 값을 반올림을 하여 합산을 하면
1 + 2 + 3 + 4= 10이 됩니다. 전체 값이 1.5 증가하는 현상이 발생합니다.
세상에는 소수점 데이터가 많습니다.
그리고 위 예시는 4개의 값만 다뤘으나 이는 통계학이나 빅데이터와 같은 많은 값을 다루는 분야에서라면 오차가 크게 발생할 수 있습니다.
즉,"반절 위치를 '올림'으로 처리하는 것은 중립적이지 못하다!"
라고 보며, 통계학에선 오사오입 반올림을 사용합니다.
반올림할 숫자가 정확히 반절 위치일 경우,
가까운 짝수 쪽으로 반올림하는 규칙입니다.
다르게 말하면 '반올림할 숫자가 절반일 경우에 그 결과는 무조건 짝수'가 됩니다. (0, 2, 4, 6, 8)
1에서와 동일한 예시를 볼까요?
0.5 + 1.5 + 2.5 + 3.5 = 8.5 인데, 오사오입 방식으로 이용하여 가까운 짝수 쪽으로 반올림을 하면
0 + 2 + 2 + 4 = 8로, 오차는 0.5가 됩니다.
좀 더 간단한 예시로 들면
0.5 + 1.5 = 2.0을
기존 방식을 반올림으로 하면 1 + 2 = 3이 되는데
오사오입으로 반올림 하면 0 + 2 = 2로 오차가 없어집니다.
즉, '반절 위치가 나올 경우, 해당 경우의 반절은 올림 또 다른 반절은 내림으로 처리하여 중립성을 만든다' 로 보면 됩니다. (균형을 맞춰라!)
파이썬은 통계학, 데이터 분석, 머신러닝 등에 자주 사용되는 프로그래밍 언어이죠?
오사오입은 자연과학, 공학, 통계에서 주로 사용하는 방식이며,
파이썬 또한 반올림 방식도 오사오입을 따르고 있습니다.
# csv 전체 가져오기 -> DataFrame
richest_dataset = pd.read_csv('TopRichestInWorld.csv')
richest_dataset
type(richest_dataset)
pandas.core.frame.DataFrame
# csv에서 특정 열만 가져오기 -> DataFrame
richest_dataset['Age']
0 50
1 58
2 73
3 66
4 91
..
96 61
97 76
98 63
99 66
100 75
Name: Age, Length: 101, dtype: int64
# csv에서 특정 열만 Series로 가져오기 -> .squeeze() -> Series
# csv에서 특정 열만 가져오기 -> DataFrame
richest_series = pd.read_csv('TopRichestInWorld.csv', usecols=['Name']).squeeze()
richest_series
0 Elon Musk
1 Jeff Bezos
2 Bernard Arnault & family
3 Bill Gates
4 Warren Buffett
...
96 Vladimir Potanin
97 Harold Hamm & family
98 Sun Piaoyang
99 Luo Liguo & family
100 Peter Woo
Name: Name, Length: 101, dtype: object
richest_series.to_csv('TopRichestInWorld_new.csv')
rich_set.head()
rich_set.tail()
rich_df.sort_values()
74 Abigail Johnson
42 Alain Wertheimer
17 Alice Walton
22 Amancio Ortega
89 Andrew Forrest
...
4 Warren Buffett
54 William Lei Ding
85 Yang Huiyan & family
24 Zhang Yiming
16 Zhong Shanshan
Name: Name, Length: 101, dtype: object
rich_df.sort_values(axis=0, ascending=False)
16 Zhong Shanshan
24 Zhang Yiming
85 Yang Huiyan & family
54 William Lei Ding
4 Warren Buffett
...
89 Andrew Forrest
22 Amancio Ortega
17 Alice Walton
42 Alain Wertheimer
74 Abigail Johnson
Name: Name, Length: 101, dtype: object
rich_df.sort_values(axis=0, ascending=False, kind='quicksort', na_position='last')
rich_df.sort_values(axis=0, ascending=False, kind='quicksort', na_position='last', ignore_index=True)
0 Zhong Shanshan
1 Zhang Yiming
2 Yang Huiyan & family
3 William Lei Ding
4 Warren Buffett
...
96 Andrew Forrest
97 Amancio Ortega
98 Alice Walton
99 Alain Wertheimer
100 Abigail Johnson
Name: Name, Length: 101, dtype: object
변수 = 원본.메소드()와 같은 문법 사용#비파과적 처리
numbers = [1, 9, 3, 6, 7]
sorted(numbers)
numbers = [1, 9, 3, 6, 7]
numbers = sorted(numbers)
numbers
# 지금까지 실습한 sort_values()결과를 저장하려면
rich_set = rich_df.sort_values(axis=0, ascending=True,
kind='quicksort', na_position='last',
ignore_index=True)
rich_set
변수 = 원본.메소드()와 같은 문법을 사용하지 않는다.원본.메소드() 반환 값은 없거나, 있다면 주로 함수 실행 성공 여부(True/False) 또는 결과를 대략 파악할 수 있는 값이 반환된다.numbers = [1, 9, 3, 6, 7]
numbers.sort()
# 카피본 만들고 사용하기
rich_df_copy = rich_df.copy()
rich_df_copy.sort_values(inplace=True)
정렬에 필요한 크고 작음의 기준을 정함
글자라면 A-Z순, 숫자라면 크고 작음
예시1
basket = ['apple', 'Banana', 'Cherry', 'durian']
basket_series = pd.Series(basket)
# 그냥 sort_values()를 하면 문자부호 순서로 소문자가 무조건 밀려난다. (아스키코드 + 유니코드)
basket_series.sort_values()
1 Banana
2 Cherry
0 apple
3 durian
dtype: object
# 만일 모두 대문자 또는 소문자라고 치고 정렬하려면?
basket_series.sort_values(key = lambda x: x.str.lower())
0 apple
1 Banana
2 Cherry
3 durian
dtype: object
💡 .str.lower() 는 현재 시리즈의 값을 모두 문자열로 만든 다음 소문자로 변환하는 코드이다.
파이썬에서도 str()같은 함수를 지원하지만, pandas는 데이터를 변환하는 과정이 많다보니
map()함수처럼 데이터 각각 처리하고 +.함수.함수 처럼 체인 형태의 코딩이 쉽도록 개선해놓는다.
# .str.lower()까지 하면?
basket_series.str.lower()
0 apple
1 banana
2 cherry
3 durian
dtype: object
rich_df.sort_values()
74 Abigail Johnson
42 Alain Wertheimer
17 Alice Walton
22 Amancio Ortega
89 Andrew Forrest
...
4 Warren Buffett
54 William Lei Ding
85 Yang Huiyan & family
24 Zhang Yiming
16 Zhong Shanshan
Name: Name, Length: 101, dtype: object
rich_df.sort_values(key=lambda x : x.str.len())
67 Jack Ma
61 Li Shufu
57 Wang Wei
0 Elon Musk
93 Li Xiting
...
84 Theo Albrecht, Jr. & family
51 Leonardo Del Vecchio & family
44 German Larrea Mota Velasco & family
13 Francoise Bettencourt Meyers & family
34 Beate Heister & Karl Albrecht Jr. & family
Name: Name, Length: 101, dtype: object
❓ [의문] lambda 인자에 들어오는 x값이 문자열이면 바로 len(x), lower(x)로 해도 되지 않나?
💡 '각 데이터는 문자열(string)로 가져온 것'이 아닌 'Series'로 가져와집니다.
key=lambda x: x.str.len()
에서 x에 담기는 데이터 유형은 Series이니 에러가 발생합니다.
rich_set.sort_index()
0 Elon Musk
1 Jeff Bezos
2 Bernard Arnault & family
3 Bill Gates
4 Warren Buffett
...
96 Vladimir Potanin
97 Harold Hamm & family
98 Sun Piaoyang
99 Luo Liguo & family
100 Peter Woo
Name: Name, Length: 101, dtype: object
rich_set.sort_index(ascending = False)
100 Peter Woo
99 Luo Liguo & family
98 Sun Piaoyang
97 Harold Hamm & family
96 Vladimir Potanin
...
4 Warren Buffett
3 Bill Gates
2 Bernard Arnault & family
1 Jeff Bezos
0 Elon Musk
Name: Name, Length: 101, dtype: object
.value_counts()
우선 나라 열만 가져오겠습니다.
# 나라 열만 가져오기 -> 시리즈 화
rich_country = pd.read_csv('TopRichestInWorld.csv', usecols=["Country/Territory"]).squeeze()
rich_country
0 United States
1 United States
2 France
3 United States
4 United States
...
96 Russia
97 United States
98 China
99 China
100 Hong Kong
Name: Country/Territory, Length: 101, dtype: object
# value_counts : collection.Counter와 비슷한 기능
rich_country.value_counts()
Country/Territory
United States 37
China 18
India 7
Germany 7
France 7
Hong Kong 4
Japan 3
Australia 2
Russia 2
Indonesia 2
Italy 2
Canada 2
Mexico 2
Austria 1
Spain 1
Switzerland 1
Chile 1
Singapore 1
Sweden 1
Name: count, dtype: int64
rich_country.value_counts(normalize=False) # 실제 수
rich_country.value_counts(normalize=True) # 백분율
Country/Territory
United States 0.366337
China 0.178218
India 0.069307
Germany 0.069307
France 0.069307
Hong Kong 0.039604
Japan 0.029703
Australia 0.019802
Russia 0.019802
Indonesia 0.019802
Italy 0.019802
Canada 0.019802
Mexico 0.019802
Austria 0.009901
Spain 0.009901
Switzerland 0.009901
Chile 0.009901
Singapore 0.009901
Sweden 0.009901
Name: proportion, dtype: float64
# 부자로 가장 유니크한 산업을 찾는다면
rich_industry.value_counts(normalize=True, sort=True)
Industry
Fashion & Retail 0.178218
Technology 0.148515
Finance & Investments 0.128713
Metals & Mining 0.089109
Food & Beverage 0.079208
Automotive 0.069307
Diversified 0.059406
Manufacturing 0.049505
Healthcare 0.049505
Media & Entertainment 0.039604
Real Estate 0.029703
Telecom 0.019802
Logistics 0.019802
Energy 0.019802
Gambling & Casinos 0.009901
Service 0.009901
Name: proportion, dtype: float64
# 부자로 가장 유니크한 산업을 찾는다면
rich_industry.value_counts(normalize=True, ascending=True)
Industry
Gambling & Casinos 0.009901
Service 0.009901
Telecom 0.019802
Logistics 0.019802
Energy 0.019802
Real Estate 0.029703
Media & Entertainment 0.039604
Manufacturing 0.049505
Healthcare 0.049505
Diversified 0.059406
Automotive 0.069307
Food & Beverage 0.079208
Metals & Mining 0.089109
Finance & Investments 0.128713
Technology 0.148515
Fashion & Retail 0.178218
Name: proportion, dtype: float64
# 나이 열만 가져오기 -> 시리즈 화
rich_age=pd.read_csv('TopRichestInWorld.csv', usecols=['Age']).squeeze()
rich_age
#bin 사용
rich_age.value_counts(bins=5)
Age
(55.6, 68.4] 33
(68.4, 81.2] 27
(81.2, 94.0] 19
(42.8, 55.6] 17
(29.935, 42.8] 5
Name: count, dtype: int64
# bins를 5로 설정하여 5구간으로 나누어 출력
data_set.value_counts(normalize=True)
banana 0.5
apple 0.5
Name: proportion, dtype: float64
data_set.value_counts(dropna=False) #결측치 사용할때 유용
banana 2
apple 2
None 1
NaN 1
Name: count, dtype: int64
rich_name[0]
rich_name[100]
# 범위를 넘기면 에러
rich_name[[0, 5, 15]]
0 Elon Musk
5 Larry Page
15 Jim Walton
Name: Name, dtype: object
# head와 동일한 기능
rich_name[0:5]
0 Elon Musk
1 Jeff Bezos
2 Bernard Arnault & family
3 Bill Gates
4 Warren Buffett
Name: Name, dtype: object
# 슬라이스 숫자 생략도 파이썬처럼 가능
rich_name[5:]
# 0~50명단까지, 5배수에 해당하는 사람 이름을 조회하려면
rich_name[4:50:5]
data = ['banana', 'apple', 'coconut']
data_se = pd.Series(data)
data_se.index
RangeIndex(start=0, stop=3, step=1)
user = {"name": "Spencer", "age": 20, "job": None}
user_se = pd.Series(user)
user_se.index
Index(['name', 'age', 'job'], dtype='object')
Index
RangeIndex vs Index 요약
del user_set['name'] : 인덱스 레이블을 사용하여 해당하는 인덱스와 값을 삭제하는 것del user_set[0] : 정수 인덱스를 사용하여 삭제하는 것이 불가능정수 인덱스? 인덱스 레이블?
삭제 연산은 레이블 접근만 허용
**import** pandas **as** pd
rich_df **=** pd.read_csv('TopRichestInWorld.csv')
rich_df
| Name | NetWorth | Age | Country/Territory | Source | Industry | |
|---|---|---|---|---|---|---|
| 0 | Elon Musk | $219,000,000,000 | 50 | United States | Tesla, SpaceX | Automotive |
| 1 | Jeff Bezos | $171,000,000,000 | 58 | United States | Amazon | Technology |
| 2 | Bernard Arnault & family | $158,000,000,000 | 73 | France | LVMH | Fashion & Retail |
| 3 | Bill Gates | $129,000,000,000 | 66 | United States | Microsoft | Technology |
| 4 | Warren Buffett | $118,000,000,000 | 91 | United States | Berkshire Hathaway | Finance & Investments |
| ... | ... | ... | ... | ... | ... | ... |
| 96 | Vladimir Potanin | $17,300,000,000 | 61 | Russia | metals | Metals & Mining |
| 97 | Harold Hamm & family | $17,200,000,000 | 76 | United States | oil & gas | Energy |
| 98 | Sun Piaoyang | $17,100,000,000 | 63 | China | pharmaceuticals | Healthcare |
| 99 | Luo Liguo & family | $17,000,000,000 | 66 | China | chemicals | Manufacturing |
| 100 | Peter Woo | $17,000,000,000 | 75 | Hong Kong | real estate | Real Estate |
101 rows × 6 columns
rich_df **=** pd.read_csv('TopRichestInWorld.csv', usecols**=**['Industry']).squeeze()
rich_df
0 Automotive
1 Technology
2 Fashion & Retail
3 Technology
4 Finance & Investments
...
96 Metals & Mining
97 Energy
98 Healthcare
99 Manufacturing
100 Real Estate
Name: Industry, Length: 101, dtype: object
rich_df **=** pd.read_csv('TopRichestInWorld.csv',
usecols**=**['Age', 'Name'], index_col **=** 'Name').squeeze()
rich_df
Name
Elon Musk 50
Jeff Bezos 58
Bernard Arnault & family 73
Bill Gates 66
Warren Buffett 91
..
Vladimir Potanin 61
Harold Hamm & family 76
Sun Piaoyang 63
Luo Liguo & family 66
Peter Woo 75
Name: Age, Length: 101, dtype: int64
rich_df.mean()
67.11881188118812
round(rich_df.mean(), 1)
67.1
rich_df.idxmin()
'Sam Bankman-Fried'
rich_df.idxmax()
'Lee Shau Kee'
rich_df.sort_values()
Name
Sam Bankman-Fried 30
Mark Zuckerberg 37
Zhang Yiming 38
Yang Huiyan & family 40
Guillaume Pousaz 40
..
Leonard Lauder 89
Rupert Murdoch & family 91
Warren Buffett 91
Li Ka-shing 93
Lee Shau Kee 94
Name: Age, Length: 101, dtype: int64
rich_df.value_counts(bins **=** 5)
Age
(55.6, 68.4] 33
(68.4, 81.2] 27
(81.2, 94.0] 19
(42.8, 55.6] 17
(29.935, 42.8] 5
Name: count, dtype: int64
rich_df.value_counts(normalize**=True**, bins **=** 5)
Age
(55.6, 68.4] 0.326733
(68.4, 81.2] 0.267327
(81.2, 94.0] 0.188119
(42.8, 55.6] 0.168317
(29.935, 42.8] 0.049505
Name: proportion, dtype: float64
rich_df.sort_values().to_csv('TopYoungestAndRichiInWorld.csv')
new_rich **=** pd.read_csv('TopYoungestAndRichiInWorld.csv')
new_rich
| Name | Age | |
|---|---|---|
| 0 | Sam Bankman-Fried | 30 |
| 1 | Mark Zuckerberg | 37 |
| 2 | Zhang Yiming | 38 |
| 3 | Yang Huiyan & family | 40 |
| 4 | Guillaume Pousaz | 40 |
| ... | ... | ... |
| 96 | Leonard Lauder | 89 |
| 97 | Rupert Murdoch & family | 91 |
| 98 | Warren Buffett | 91 |
| 99 | Li Ka-shing | 93 |
| 100 | Lee Shau Kee | 94 |
101 rows × 2 columns