판다스, 시리즈 다루기 - 응용
시리즈와 불린 추출
추출할 데이터의 정확한 인덱스를 모르는 경우가 많습니다.
이런경우에 사용하는 방법이 불린 추출입니다. 불린 추출은 특정 조건을 만족하는 값만 추출할 수 있습니다.
시리즈와 불린 추출 사용하기
1.이번에는 'scientists.csv'라는 이름의 데이터를 불러옵니다.
scientists = pd.read_csv('. ./data/scientists.csv')
2. 통계 수치의 결괏값을 이용하여 불린 추출을 진행해 보겠습니다.
다음은 Age열을 추출하여 max, mean 메서드를 사용한 것입니다.
ages = scientists['Age']
print(ages.max())
90
print(ages.mean())
59. 125
3. 이제 불린 추출을 사용할 차례입니다. 예를 들어 평균 나이보다 나이가 많은 사람의 데이터를
추출하려면 어떻게 해야 할까요? 다음 코드를 실행하면 평균 나이보다 나이가 많은 사람의
데이터만 출력됩니다.
print(ages[ages > ages.mean()])
1 61
2 90
3 66
7 77
Name: Age, dtype: int64
print(type(ages > ages.mean()))
<class 'pandas.core.series.Series'>
4. 먼저 ages > ages.mean( )의 결과를 출력해 보겠습니다. 그러면 1, 2, 3, 7 인덱스의 데이터가 참(True)
이라는 것을 알 수 있습니다. 즉, 조건식을 만족한 값만 출력된 것이죠.
print(ages > ages.mean())
0 False
1 True
2 True
3 True
4 False
5 False
6 False
7 True
Name: Age, dtype: bool
print(type(ages > ages.mean()))
<class 'pandas.core.series.Series'>
5. 과정 3과 4를 모두 합친 코드는 다음과 같습니다. 즉, 리스트 형태로 참이나 거짓을 담아
시리즈에 전달하면 참인 인덱스의 데이터만 추출할 수 있습니다. 바로 이것을 불린 추출이라고 합니다.
manual_bool_values = [True, True, False, False, True, True, False, True]
print(ages[manual_bool_values])
0 37
1 61
4 56
5 45
7 77
Name: Age, dtype: int64
시리즈와 브로드캐스팅
그런데 ages > ages.mean( )의 결괏값의 개수가 여러 개라는 것이 이상하지 않았나요?
이렇게 시리즈나 데이터프레임에 있는 모든 데이터에 대해 한 번에 연산하는 것을 브로드캐스팅 이라고 합니다.
그리고 시리즈처럼 여러 개의 값을 가진 데이터를 벡터라 하고 단순 크기를 나타내는 데이터를 스칼라라고 합니다.
앞으로 벡터와 스칼라라는 용어는 자주 사용하므로 기억해 둡시다.
*시리즈는 벡터의 한종류 입니다
벡터와 스칼라로 브로드캐스팅 수행하기
1.다음은 같은 길이의 벡터로 더하기 연산과 곱하기 연산을 수행한 것입니다. 결괏값으로 같은 길이의
벡터가 출렵됩니다.
print(ages + ages)
0 74
1 122
2 180
3 132
4 112
5 90
6 82
7 154
Name: Age, dtype: int64
print(ages * ages)
0 1369
1 3721
2 8100
3 4356
4 3136
5 2025
6 1681
7 5929
Name: Age, dtype: int64
2. 만약 벡터에 스칼라를 연산하면 어떻게 될까요? 다음은 벡터의 모든 값에 스칼라를 적용하여
브로드캐스팅한 결과입니다.
print(ages + 100)
0 137
1 161
2 190
3 166
4 156
5 145
6 141
7 177
Name: Age, dtype: int64
print(ages * 2)
0 74
1 122
2 180
3 132
4 112
5 90
6 82
7 154
Name: Age, dtype: int64
3. 길이가 서로 다른 벡터를 연산하면 어떻게 될까요? 시리즈와 시리즈를 연산하는 경우 같은 인덱스의
값만 계산합니다. 다음은 데이터의 개수가 2개인 시리즈와 8개인 시리즈를 더한 것입니다.
결괏값을 살펴보면 인덱스가 일치한 0, 1만 계산했다는 것을 알 수 있습니다.
나머지 인덱스(2~7)는 계산을 할 수 없기 때문에 누락값(NaN)으로 처리합니다.
* 벡터의 자료형에 따라 브로드캐스팅 방식이 달라집니다.
print(pd.Series([1, 100]))
0 1
1 100
dtype: int64
print(ages + pd.Series([1, 100]))
0 38.0
1 161.0
2 NaN
3 NaN
4 NaN
5 NaN
6 NaN
7 NaN
dtype: float64
4. 다음은 sort_index 메서드를 사용한 것입니다. 이때 ascending 인자로 False를 전달하여
인덱스 역순으로 데이터를 정렬했습니다.
rev_ages = ages.sort_index(ascending=False)
print(rev_ages)
7 77
6 41
5 45
4 56
3 66
2 90
1 61
0 37
Name: Age, dtype: int64
5. 그러면 인덱스 순서대로 정렬된 ages와 인덱스의 역순으로 정렬된 rev_age를 연산하면 어떻게 될까요?
ages의 데이터와 rev_ages의 데이터를 순서대로 더할 것 같지만 그렇지 않습니다.
다음은 ages * 2와 ages + rev_ages의 결괏값을 출력한 것입니다. 어떤가요?
ages * 2와 ages + rev_ages의 결괏값이 동일합니다. ages의 인덱스(0~7)와 rev_ages의 인덱스(0~7)가
일치하는 값끼리 연산했기 때문이죠. 벡터와 벡터의 연산은 일치하는 인덱스의 값끼리 수행한다는
것을 잊지 마세요.
print(ages * 2)
0 74
1 122
2 180
3 132
4 112
5 90
6 82
7 154
Name: Age, dtype: int64
print(ages + rev_ages)
0 74
1 122
2 180
3 132
4 112
5 90
6 82
7 154
Name: Age, dtype: int64
출처 : doit 데이터 분석을 위한 판다스 입문