Pandas로 최대 두 개 이상의 열 찾기


105

나는 열이있는 dataframe을 가지고 A, B. C모든 레코드 / 행에 대해 다음과 같은 열을 만들어야합니다 .

C = max(A, B).

이 작업을 어떻게해야합니까?

답변:


198

다음과 같이 최대 값을 얻을 수 있습니다.

>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
>>> df
   A  B
0  1 -2
1  2  8
2  3  1
>>> df[["A", "B"]]
   A  B
0  1 -2
1  2  8
2  3  1
>>> df[["A", "B"]].max(axis=1)
0    1
1    8
2    3

그래서 :

>>> df["C"] = df[["A", "B"]].max(axis=1)
>>> df
   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

"A"와 "B"가 유일한 열이라는 것을 알고 있다면

>>> df["C"] = df.max(axis=1)

그리고 당신도 사용할 수 있습니다 .apply(max, axis=1).


2
.apply(max, axis=1)훨씬 느린보다.max(axis=1)
RajeshM

30

@DSM의 대답은 거의 모든 정상적인 시나리오에서 완벽합니다. 그러나 표면 수준보다 조금 더 깊이 들어가고 싶은 프로그래머 유형이라면 직접적으로가 아니라 기본 .to_numpy()(또는 .values<0.24) 배열 에서 numpy 함수를 호출하는 것이 조금 더 빠르다는 것을 알고 싶을 것입니다. DataFrame / Series 객체에 정의 된 (cythonized) 함수를 호출합니다.

예를 들어 ndarray.max()첫 번째 축을 따라 사용할 수 있습니다 .

# Data borrowed from @DSM's post.
df = pd.DataFrame({"A": [1,2,3], "B": [-2, 8, 1]})
df
   A  B
0  1 -2
1  2  8
2  3  1

df['C'] = df[['A', 'B']].values.max(1)
# Or, assuming "A" and "B" are the only columns, 
# df['C'] = df.values.max(1) 
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3 

데이터에 NaNs가 있으면 다음이 필요합니다 numpy.nanmax.

df['C'] = np.nanmax(df.values, axis=1)
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3 

당신은 또한 사용할 수 있습니다 numpy.maximum.reduce. numpy.maximumufunc (범용 함수) 이고 모든 ufunc에는 다음이 있습니다reduce .

df['C'] = np.maximum.reduce(df['A', 'B']].values, axis=1)
# df['C'] = np.maximum.reduce(df[['A', 'B']], axis=1)
# df['C'] = np.maximum.reduce(df, axis=1)
df

   A  B  C
0  1 -2  1
1  2  8  8
2  3  1  3

여기에 이미지 설명 입력

np.maximum.reduce그리고 np.max더 많거나 적은 (가장 일반적인 크기의 DataFrames의 경우) 동일 - 그리고 그늘보다 더 빨리 될 일이 나타납니다 DataFrame.max. 이 차이는 대략 일정하게 유지되며 내부 오버 헤드 (인덱싱 정렬, NaN 처리 등) 때문이라고 생각합니다.

그래프는 perfplot을 사용하여 생성 되었습니다 . 참조 용 벤치마킹 코드 :

import pandas as pd
import perfplot

np.random.seed(0)
df_ = pd.DataFrame(np.random.randn(5, 1000))

perfplot.show(
    setup=lambda n: pd.concat([df_] * n, ignore_index=True),
    kernels=[
        lambda df: df.assign(new=df.max(axis=1)),
        lambda df: df.assign(new=df.values.max(1)),
        lambda df: df.assign(new=np.nanmax(df.values, axis=1)),
        lambda df: df.assign(new=np.maximum.reduce(df.values, axis=1)),
    ],
    labels=['df.max', 'np.max', 'np.maximum.reduce', 'np.nanmax'],
    n_range=[2**k for k in range(0, 15)],
    xlabel='N (* len(df))',
    logx=True,
    logy=True)

작은 오타 : "df [ 'C'] = np.maximum.reduce (df [ 'A', 'B']]. values, axis = 1)"은 "df [ 'C'] = np.maximum. reduce (df [[ 'A', 'B']]. values, axis = 1) "
Velizar VESSELINOV
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.