Pandas의 map, applymap 및 apply 메소드의 차이점


465

이러한 벡터화 방법을 기본 예제와 함께 사용하는시기를 알려주시겠습니까?

그 볼 mapA는 Series있는 나머지 반면, 방법 DataFrame방법. 나는 혼동있어 applyapplymap방법하지만. 왜 DataFrame에 함수를 적용하는 두 가지 방법이 있습니까? 사용법을 보여주는 간단한 예제도 훌륭합니다!


5
내가 틀렸다면 수정하십시오. 그러나 해당 함수는 적용되는 요소를 모두 반복하기 때문에 메소드를 벡터화하지 않습니다.
Tanguy

답변:


533

Wes McKinney의 Python for Data Analysis 책에서 바로 pg. 132 (이 책을 강력히 추천합니다) :

또 다른 빈번한 작업은 1D 배열의 함수를 각 열 또는 행에 적용하는 것입니다. DataFrame의 apply 메소드는 정확히 다음을 수행합니다.

In [116]: frame = DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [117]: frame
Out[117]: 
               b         d         e
Utah   -0.029638  1.081563  1.280300
Ohio    0.647747  0.831136 -1.549481
Texas   0.513416 -0.884417  0.195343
Oregon -0.485454 -0.477388 -0.309548

In [118]: f = lambda x: x.max() - x.min()

In [119]: frame.apply(f)
Out[119]: 
b    1.133201
d    1.965980
e    2.829781
dtype: float64

가장 일반적인 배열 통계 (sum 및 mean과 같은)는 DataFrame 메서드이므로 apply를 사용할 필요가 없습니다.

요소 별 파이썬 함수도 사용할 수 있습니다. 프레임의 각 부동 소수점 값에서 형식화 된 문자열을 계산하려고한다고 가정하십시오. applymap으로이를 수행 할 수 있습니다.

In [120]: format = lambda x: '%.2f' % x

In [121]: frame.applymap(format)
Out[121]: 
            b      d      e
Utah    -0.03   1.08   1.28
Ohio     0.65   0.83  -1.55
Texas    0.51  -0.88   0.20
Oregon  -0.49  -0.48  -0.31

applymap이라는 이름의 이유는 Series에 요소 별 함수를 적용하기위한 map 메소드가 있기 때문입니다.

In [122]: frame['e'].map(format)
Out[122]: 
Utah       1.28
Ohio      -1.55
Texas      0.20
Oregon    -0.31
Name: e, dtype: object

요약 apply하면 DataFrame의 행 / 열 기준으로 applymap작동 하고 DataFrame에서 요소별로 map작동하며 Series에서 요소별로 작동합니다.


31
엄격히 말해서, applymap 내부적으로 전달 된 함수 매개 변수에 대한 약간의 마무리 ( 적용하게 대체 func하고 lambda x: [func(y) for y in x]열 방식으로 적용)를 통해 apply를 통해 내부적으로 적용됩니다.
alko

5
설명 주셔서 감사합니다. 이후 mapapplymap작업 요소 많다는 모두, 나는 하나의 방법 (중 기대 map또는 applymap시리즈와 DataFrame 모두를 작동합니다). 아마도 다른 디자인 고려 사항이있을 수 있으며 Wes McKinney는 두 가지 다른 방법을 결정하기로 결정했습니다.
marillion

2
어떤 이유로 내 사본에 129 페이지에 있습니다. 2 판 또는 기타 라벨은 없습니다.
Jody

1
팬더의 기능 applymap과 함께 할 수있는 방법이 groupby있습니까?
everestial007

그룹화 된 열 단위 데이터에 함수를 적용하는 방법은 무엇입니까?
hhh

83

비교 map, applymap그리고 : 컨텍스트 사항을apply

첫 번째 주요 차이점 : 정의

  • map 시리즈에만 정의됩니다
  • applymap DataFrames에서만 정의됩니다.
  • apply BOTH에 정의되어 있습니다.

두 번째 주요 차이점 : 입력 인수

  • map받아 dict들, Series또는 호출을
  • applymap그리고 apply단지 callables을 받아

세 번째 주요 차이점 : 행동

  • map 시리즈의 요소입니다
  • applymap DataFrames의 요소 단위입니다.
  • apply또한 요소 단위로 작동하지만 더 복잡한 작업 및 집계에 적합합니다. 동작 및 반환 값은 기능에 따라 다릅니다.

네 번째 주요 차이점 (가장 중요한 것) : USE CASE

  • map그래서 성능에 최적화되어, 한 도메인에서 다른 도메인으로 매핑 값을 의미한다 (예 df['A'].map({1:'a', 2:'b', 3:'c'}))
  • applymap이다 다수의 행 / 열에서 elementwise 변환을위한 좋은 (예 df[['A', 'B', 'C']].applymap(str.strip))
  • apply벡터화 할 수없는 어떤 기능을 적용하기위한 것이다 (예 df['sentences'].apply(nltk.sent_tokenize))

요약

여기에 이미지 설명을 입력하십시오

각주

  1. map사전 / 시리즈가 전달되면 해당 사전 / 시리즈의 키를 기반으로 요소를 매핑합니다. 결 측값은 출력에서 ​​NaN으로 기록됩니다.
  2. applymap최신 버전에서는 일부 작업에 맞게 최적화되었습니다. 당신은 발견 할 것이다 applymap약간보다 빠른 apply경우도있다. 내 제안은 둘 다 테스트하고 더 잘 작동하는 것을 사용하는 것입니다.

  3. map요소 별 매핑 및 변환에 최적화되어 있습니다. 사전 또는 시리즈와 관련된 작업을 수행하면 팬더가 더 빠른 코드 경로를 사용하여 성능을 향상시킬 수 있습니다.

  4. Series.apply집계 연산에 대한 스칼라를 리턴하고 그렇지 않으면 Series를 리턴합니다. 마찬가지로 DataFrame.apply. 주 apply와 같은 특정 NumPy와 함수를 호출하는 경우도 FastPaths와있다 mean, sum

70

이 답변에는 훌륭한 정보가 있지만 배열 방식과 요소 방식으로 작동하는 방법을 명확하게 요약하기 위해 내 자신을 추가하고 있습니다. jeremiahbuddha는 대부분이 작업을 수행했지만 Series.apply는 언급하지 않았습니다. 의견을 말할 담당자가 없습니다.

  • DataFrame.apply 한 번에 전체 행 또는 열에서 작동합니다.

  • DataFrame.applymap, Series.applySeries.map한 번에 하나의 요소에서 작동합니다.

의 기능과 중복이 많이 있습니다 Series.applySeries.map중 하나는 대부분의 경우에 작동합니다 의미는. 그들은 약간의 차이가 있지만 그 중 일부는 osa의 답변에서 논의되었습니다.


38

다른 답변에 추가하여 mapapplySeries있습니다 .

Apply는 DataFrame을 계열로 만들 수 있습니다 . 그러나 map은 다른 시리즈의 모든 셀에 시리즈를 넣을 것입니다.

In [40]: p=pd.Series([1,2,3])
In [41]: p
Out[31]:
0    1
1    2
2    3
dtype: int64

In [42]: p.apply(lambda x: pd.Series([x, x]))
Out[42]: 
   0  1
0  1  1
1  2  2
2  3  3

In [43]: p.map(lambda x: pd.Series([x, x]))
Out[43]: 
0    0    1
1    1
dtype: int64
1    0    2
1    2
dtype: int64
2    0    3
1    3
dtype: int64
dtype: object

또한 "웹 서버에 연결"과 같은 부작용이있는 기능을 가지고 있다면 apply명확성을 위해 아마도 사용할 것입니다 .

series.apply(download_file_for_every_element) 

Map함수뿐만 아니라 사전이나 다른 시리즈도 사용할 수 있습니다. 순열 을 조작하고 싶다고 가정 해 봅시다 .

갖다

1 2 3 4 5
2 1 4 5 3

이 순열의 제곱은

1 2 3 4 5
1 2 5 3 4

를 사용하여 계산할 수 있습니다 map. 자체 응용 프로그램이 문서화되어 있는지 확실하지 않지만에서 작동합니다 0.15.1.

In [39]: p=pd.Series([1,0,3,4,2])

In [40]: p.map(p)
Out[40]: 
0    0
1    1
2    4
3    2
4    3
dtype: int64

3
또한 .apply ()를 사용하면 kwargs를 함수에 전달할 수 있지만 .map ()에서는 그렇지 않습니다.
neilxdims

19

@jeremiahbuddha는 applymap이 요소 단위로 작동하는 동안 행 / 열에 적용되는 것으로 언급했습니다. 그러나 여전히 요소 별 계산에 apply를 사용할 수 있습니다 ....

    frame.apply(np.sqrt)
    Out[102]: 
                   b         d         e
    Utah         NaN  1.435159       NaN
    Ohio    1.098164  0.510594  0.729748
    Texas        NaN  0.456436  0.697337
    Oregon  0.359079       NaN       NaN

    frame.applymap(np.sqrt)
    Out[103]: 
                   b         d         e
    Utah         NaN  1.435159       NaN
    Ohio    1.098164  0.510594  0.729748
    Texas        NaN  0.456436  0.697337
    Oregon  0.359079       NaN       NaN

29
이것으로 잘 잡습니다. 이 예제에서 작동하는 이유는 np.sqrt가 ufunc이기 때문입니다. 즉, 배열을 제공하면 sqrt 함수를 배열의 각 요소에 브로드 캐스트합니다. 따라서 apply가 각 열에서 np.sqrt를 푸시하면 np.sqrt는 열의 각 요소에서 자체적으로 작동하므로 applymap과 동일한 결과를 얻습니다.
jeremiahbuddha

11

내가 조금 고생하면서 지적하고 싶었다.

def f(x):
    if x < 0:
        x = 0
    elif x > 100000:
        x = 100000
    return x

df.applymap(f)
df.describe()

이것은 데이터 프레임 자체를 수정하지 않으므로 다시 할당해야합니다.

df = df.applymap(f)
df.describe()

1
df로 무언가를 한 후에 재 할당해야하는지 여부를 알아내는 데 때때로 어려움이 있습니다. 그것은 대부분 시행 착오이지만 그것이 어떻게 작동하는지에 대한 논리가 있습니다 (내가 누락되었습니다).
marillion

2
일반적으로 팬더 데이터 프레임은 재 할당 df = modified_df또는 inplace=True플래그 를 설정 한 경우 에만 수정됩니다 . 또한 데이터 프레임을 참조로 함수에 전달하고 함수가 데이터 프레임을 수정하면 데이터 프레임이 변경됩니다.
muon

1
이것은 완전히 사실이 아니다, 생각 .ix또는 .where등 확실하지 전체 설명하면 재 할당 및 사용하지 않을 때는해야 할 때입니다 무엇.
Thanos

10

applymap과 applymap의 차이점에 대한 가장 간단한 설명은 다음과 같습니다.

apply 는 전체 열을 매개 변수로 사용하고 결과를이 열에 지정합니다

applymap 은 별도의 셀 값을 매개 변수로 사용하여 결과를이 셀에 다시 지정합니다.

NB apply가 단일 값을 반환하면 할당 후 열 대신이 값을 갖게되고 결국 행렬 대신 행만 갖게됩니다.


3

내 이해 :

기능 관점에서 :

함수에 열 / 행 내에서 비교해야하는 변수가있는 경우을 사용하십시오 apply.

예 : lambda x: x.max()-x.mean().

기능이 각 요소에 적용되는 경우 :

1> 열 / 행이있는 경우 apply

2> 전체 데이터 프레임에 적용되는 경우 applymap

majority = lambda x : x > 17
df2['legal_drinker'] = df2['age'].apply(majority)

def times10(x):
  if type(x) is int:
    x *= 10 
  return x
df2.applymap(times10)

코드를 테스트 할 수 있도록 명확성을 높이기 위해 df2도 제공하십시오.
Ashish Anand

1

cs95 의 답변을 바탕으로

  • map 시리즈에만 정의됩니다
  • applymap DataFrames에서만 정의됩니다.
  • apply BOTH에 정의되어 있습니다.

몇 가지 예를 들어

In [3]: frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])

In [4]: frame
Out[4]:
            b         d         e
Utah    0.129885 -0.475957 -0.207679
Ohio   -2.978331 -1.015918  0.784675
Texas  -0.256689 -0.226366  2.262588
Oregon  2.605526  1.139105 -0.927518

In [5]: myformat=lambda x: f'{x:.2f}'

In [6]: frame.d.map(myformat)
Out[6]:
Utah      -0.48
Ohio      -1.02
Texas     -0.23
Oregon     1.14
Name: d, dtype: object

In [7]: frame.d.apply(myformat)
Out[7]:
Utah      -0.48
Ohio      -1.02
Texas     -0.23
Oregon     1.14
Name: d, dtype: object

In [8]: frame.applymap(myformat)
Out[8]:
            b      d      e
Utah     0.13  -0.48  -0.21
Ohio    -2.98  -1.02   0.78
Texas   -0.26  -0.23   2.26
Oregon   2.61   1.14  -0.93

In [9]: frame.apply(lambda x: x.apply(myformat))
Out[9]:
            b      d      e
Utah     0.13  -0.48  -0.21
Ohio    -2.98  -1.02   0.78
Texas   -0.26  -0.23   2.26
Oregon   2.61   1.14  -0.93


In [10]: myfunc=lambda x: x**2

In [11]: frame.applymap(myfunc)
Out[11]:
            b         d         e
Utah    0.016870  0.226535  0.043131
Ohio    8.870453  1.032089  0.615714
Texas   0.065889  0.051242  5.119305
Oregon  6.788766  1.297560  0.860289

In [12]: frame.apply(myfunc)
Out[12]:
            b         d         e
Utah    0.016870  0.226535  0.043131
Ohio    8.870453  1.032089  0.615714
Texas   0.065889  0.051242  5.119305
Oregon  6.788766  1.297560  0.860289

0

FOMO :

다음 예제는을 보여 apply주고 applymap적용합니다 DataFrame.

map기능은 Series에만 적용되는 것입니다. map DataFrame 에는 신청할 수 없습니다 .

기억해야 할 점은이 apply할 수있는 아무것도 applymap 깡통을하지만, apply추가 옵션을.

은 X 팩터의 옵션은 다음과 같습니다 axisresult_type경우 result_type에만 작동 axis=1(열의).

df = DataFrame(1, columns=list('abc'),
                  index=list('1234'))
print(df)

f = lambda x: np.log(x)
print(df.applymap(f)) # apply to the whole dataframe
print(np.log(df)) # applied to the whole dataframe
print(df.applymap(np.sum)) # reducing can be applied for rows only

# apply can take different options (vs. applymap cannot)
print(df.apply(f)) # same as applymap
print(df.apply(sum, axis=1))  # reducing example
print(df.apply(np.log, axis=1)) # cannot reduce
print(df.apply(lambda x: [1, 2, 3], axis=1, result_type='expand')) # expand result

참고로 Series map함수는 Python map함수 와 혼동해서는 안됩니다 .

첫 번째는 Series에 적용되어 값을 매핑하고 두 번째는 Iterable의 모든 항목에 매핑됩니다.


마지막으로 dataframe apply방법을 groupby apply방법 과 혼동하지 마십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.