map과 filter는 내장함수이고, reduce는 from functools에서 import 해야한다.
map(func, iterable)
map 함수는 iterable의 원소를 하나씩 input으로 받아 함수를 적용한 return 값을 순서대로 적용한 iterable한 객체를 return한다. (list로 변환하면 원소를 확인할 수 있다.)
이때, iterable 2개를 받으면 각각 하나씩 꺼내오기 때문에 func 또한 원소를 2개 받는 함수를 사용해야한다.
filter(func, iterable)
filter 함수도 동일하게 iterable의 원소를 하나씩 input으로 받아 함수를 통과시켜 그 결과가 True인 원래 원소들만을 모은 iterable 객체를 return한다.
func=None으로 설정하면 항등함수를 적용하는 듯 하다. (전부 return이 아님)
iterable 자체의 값이 False이면 return하지 않기 때문
reduce(func, iterable[, initializer])
초기값과 iterable의 원소를 하나씩 가져와 함수를 적용한다.
즉 func는 초기값, 각 원소 순의 2개의 값을 매개변수로 받아야한다.
만약 initializer를 정의하지 않으면 iterable의 첫 원소를 초기값으로 설정한다.
그리고 iterable을 빈 객체로 주고, 초기값을 주면 초기값을 return 하지만
iterable을 빈 객체로 주고, 초기값을 안주면 error가 발생한다.
pd.Series().map(func)
series의 각 원소에 func를 적용한 값을 series로 모은 값을 return한다.
특이한 점은 함수 뿐만 아니라, dict나 series를 매개변수로 받을 수 있다는 점이다.
dict는 key를 input으로 value를 output으로 하는 함수라고 취급하는 것이고,
series는 index를 input으로 값을 output으로 하는 함수라고 취급하는 구현을 한 것으로 보인다.
pd.DataFrame().apply(func) / pd.Series().apply(func)
apply는 series 전체에 함수를 적용하는 메소드로
DataFrame은 복수개의 series라고 취급해 복수개의 series에 각 func를 적용하는 것이고, 당연하게도 Series는 객체는 단수개의 series라고 취급해 func를 적용한다고 생각하면된다.
element-wise나 aggregation으로 설명하는 경우도 있는데, 그건 pandas의 series의 특성이라고 보면되는 듯 하다.(다르게 구현하려면 할 수 있었겠지만 같은 이름을 사용하는데 다르게 구현했을 확률은 없다고 예상.)
즉, series에 mean을 사용하면 aggregation으로 생각하는 것이고, +100 같은 경우는 element-wise라고 생각하는 것이지만, 실제로 series는 apply와 상관없이 어떤 메소드에 대해서는 aggregation 처럼 작용하기도하고, +(add) 같은 경우는 element-wise로 계산되게 overriding 해놓은 것 뿐이므로, apply의 특징이라기보단 apply가 series에 직접 함수를 적용하는 것으로 이해하는 것이 맞다.
(따라서 series의 특성을 따르는 것이 이상하지 않다.)
따라서, scalar, series, dataframe 모두 return할 수 있는 것 뿐이다.
pd.DataFrame().applymap(func)
map은 series를 원소로 받고, 각 원소에 함수를 적용하고,
apply는 series들을(복수개일땐 DataFrame, 단수개일땐 Series) 원소로 받고,
series에 직접 함수를 적용하기 때문에,
DataFrame을 원소로 받아 각 원소(cell)에 함수를 적용하는 메소드를 만들 필요성이 있었던 것으로 보인다.
당연하게도 return값도 DataFrame이다.