Point operator+(const Point& ref);
// 사용시 해석
pos.operator+(pos2);
2)전역 함수 오버로딩
구현 : 전역 함수로 구현하고 클래스 내에서 friend 정의
멤버 변수 접근 안되므로 getter 또는 friend 필요!
// 클래스 내부에서 정의
friend Point operator+(Point&, Point&);
// 클래스 밖에서 전역 함수 구현
Point operator+(Point& pos1, Point& pos2){}
// 사용시 해석
operator+(pos1, pos2);
무조건 전역 함수 오버로딩을 사용하는 경우
이항 연산의 왼쪽항이 오버로딩 객체가 아닐 때 사용
Point 객체에 상수 3을 곱할 경우
Point operator*(int, Point&);
//사용
Point pos2 = pos * 3;
객체를 cout 가능하게 하기
ostream을 전역 함수 오버로딩 사용
ostream& operator<<(ostream& os, Point& pos){
os <<'('<< x << ',' << y << ')' << endl;
return os;
}
연산자 오버로딩 시 주의 사항
Animal 클래스(부모) 에서 연산자 오버로딩
Cat 클래스(자식)에서 연산자 오버로딩 안함
위의 상태에서 연산자 오버로딩 사용시 문제 발생 가능
if (Cat1 == Cat2)
// 서로 다른 객체 이지만 부모가 동일하여 True발생 가능함
// Cat에도 연산자 오버로딩을 작성해야 함!
// 예외를 던지는 함수
void Divide(int num1, int num2){
if(num2 == 0)
trhow num2;
}
// 함수를 콜하는 부분
// Divide 함수 수행 하다 예외 발생시
// 아래 catch 부분에서 예외 처리 가능
try{
Divide(num1, num2);
} catch(int expn){ ... }
함수 선언시 throw 키워드 추가
예외 발생이 있다면 throw 키워드를 꼭 붙여야함!
int Func(int num) throw(int, char)
// int와 char 형식의 예외 발생이 가능하다!
// 이 함수 사용시 try catch문이 필요하다고 알림
클래스 형태로 예외 정의 가능
예외 클래스를 정의
예외 클래스는 exception 클래스를 상속!
void deposit(money) {
if ( money < 0 ) {
//expn 예외 객체 생성 및 throw 발생
DepositException expn(money) ;
throw expn;
}
}
try {
deposit(-200) ;
} catch ( DepositException &expn) {
expn.showError();
}
17. C++ 형변환 연산자
dynamic_cast(expr)
상속 관계에서 안전한 형 변환 가능
T에 객체는 포인터 또는 참조형 가능
실행시간에 형변환 되므로 속도 느림
static_cast(expr)
C스타일의 형변환 연산자 대신 사용
컴파일 시간에 형변환 되므로 속도 빠름
설계 잘되어 있다면 dynamic 대신 static 사용
const_cast(expr)
참조자의 const 성향을 제거하는 형변환
주로 인자 전달시 불일치 제거를 위해 사용
reinterpret_cast(expr)
전혀 상관이 없는 형 변환에 사용
18. 함수 포인터
정적 함수 호출
일반 함수나 static 멤버 함수를 가리키는 포인터
선언
// 선언
void (*pFunc)(int);
// 반환값이 void이고 인자가 int형 하나인 함수를 가리킬 수 있는 함수 포인터
멤버 함수 호출
선언
void(Point::*pFunc)();
// 반환값이 void이고 인자가 없는 Point 멤버 함수를 가리킬 수 있는 함수 포인터 선언
//사용
Point pt;
(pt.*pFunc)(); // 객체로 사용
Point *p;
(p->*pFunc)(); // 주소로 사용
19. 함수 객체
장점
객체 이므로 멤버 변수, 멤버 함수를 가질 수 있음
속도가 일반 함수보다 빠름
인라인화 될 수 있음(함수 포인터는 안됨)
컴파일러가 쉽게 최적화 가능
//선언
struct Adder{
int operator()(int a, int b){
return a_b;
}
};
int main(){
// 사용1
Adder add;
add(3,2);
// 사용2 : 인자로 전달
for_each(arr, arr+5, Adder());
}
print 함수 구현시 ostream&을 인자로 사용하면, 상속 구조에 따라 ostreamstream, ofstream도 사용 가능
//사용 1. cout
print(cout) => 화면에 결과 출력
//사용 2. fstream
ofstream ofs{"test.txt"};
print(ofs) => 파일에 결과 쓰기
//사용 3. stringstream
stringstream ss;
print(ss) => string에 쓰기
집계함수란 데이터를 몇몇의 집단으로 나누어 집단간 평균, 합계 등의 연산을 수행하는 함수를 얘기합니다. 예를 들어 고등학교 학생 전체 성적 데이터가 있을 경우 반별로 영어성적에 대한 평균을 내거나, 과목별로 학생들의 성적에 대한 평균을 내는 것과 같습니다. 예와 같이 집계함수를 적용하기 위해서는 3가지 값이 필요하며, 그 값은 그룹할 기준(반별 또는 과목별), 연산을 수행할 값(영어성적), 연산 함수(평균) 입니다.
이번 포스팅에서 소개할 내용을 요약하면 아래와 같습니다.
groupby 함수을 사용한 DataFrame 집계
pivot_table 함수를 사용한 DataFrame 집계
실습에 사용한 데이터는 fifa19에 등장하는 축구선수들의 능력치 데이터입니다. 데이터는 아래에서 다운로드 받을 수 있습니다.
9. DataFrame의 집계함수
DataFrame을 집계할 수 있는 두 개의 함수
groupby
pivot_table
9.1 groupby 함수
groupby 함수를 사용한 집계 연산은 두 단계로 이루어짐
DataFrame을 그룹별로 나누는 단계
나누어진 그룹에서 집계 함수(sum, mean, max 등)를 수행하는 단계
Library import
import pandas as pd
from pandas import Series , DataFrame
import numpy as np
player = pd.read_csv('data/Ch10_1_fifaStats2.csv')
player.head()
Series와 DataFrame을 다루다 보면 각각의 열/행 데이터에 함수를 일괄적으로 적용해야 할 때가 있습니다.
이번 포스팅에서는 Series와 DataFrame의 요소에 함수를 적용하는 방법에 대해 알아보겠습니다.
소개할 내용은 아래와 같습니다.
Series 각각 요소에 함수 일괄 적용(map함수)
DataFrame의 행, 열 별 함수 일괄 적용(apply함수)
DataFrame의 요소에 함수 일괄 적용(applymap함수)
8. Series와 DataFrame에 외부 함수 적용하기
map 함수 : Series에서 사용하며 모든 요소에 함수 일괄 적용
apply 함수 : DataFrame에서 사용하며 각각의 행 또는 열(Series)에 함수 일괄 적용
applymap 함수 : DataFrame에서 사용하며 모든 요소에 함수 일괄 적용
8.1 Series의 각각의 요소에 함수 적용하기
map(Function name)
Series에서 사용가능한 함수
Series의 모든값(values)에 대해 입력된 함수 일괄 적용
pandas library import
import pandas as pd
from pandas import Series , DataFrame
srAge = Series([10,13,15,23,22,36])
srAge
0 10
1 13
2 15
3 23
4 22
5 36
dtype: int64
나이의 범위에 따라 10대, 20대, 30대로 변경하는 함수 생성
10~19 : 10대
20~29 : 20대
30~39 : 30대
그외 : NaN값
으로 변경
def weekday2weeknumber(age):
if age >= 10 and age < 20:
ageRange = '10대'
elif age >= 20 and age < 30:
ageRange = '20대'
elif age >= 30 and age < 40:
ageRange = '30대'
else:
ageRange = pd.np.nan
return ageRange
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6CA2E6A0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6CA2D898>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6C860080>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6C8872E8>]],
dtype=object)
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E38F1D0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E6F50B8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E3D6358>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E3FD898>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E426E10>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E4573C8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E47F940>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E4A8EF0>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E4A8F28>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E4FE9E8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E525F60>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E556518>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E580A90>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E5B2048>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E5D95C0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000020A6E601B38>]],
dtype=object)