Pandas fillna ()에 인수로 다른 전체 열을 전달하는 방법


94

fillna방법을 사용하여 한 열의 누락 된 값을 다른 열의 값으로 채우고 싶습니다 .

(각 행을 반복하는 것은 매우 나쁜 습관이며 모든 것을 한 번에 수행하는 것이 더 좋을 것이라고 읽었지만을 사용하여 수행하는 방법을 찾을 수 없었습니다 fillna.)

이전 데이터 :

Day  Cat1  Cat2
1    cat   mouse
2    dog   elephant
3    cat   giraf
4    NaN   ant

이후 데이터 :

Day  Cat1  Cat2
1    cat   mouse
2    dog   elephant
3    cat   giraf
4    ant   ant

답변:


173

이 열을 제공 할 수 있습니다 fillna( docs 참조 ), 일치하는 색인에서 해당 값을 사용하여 채 웁니다.

In [17]: df['Cat1'].fillna(df['Cat2'])
Out[17]:
0    cat
1    dog
2    cat
3    ant
Name: Cat1, dtype: object

7
좋은! fillna시리즈 가 필요한지 몰랐습니다 .
Ami Tavory

1
감사! 나는 세리가 NA 값의 정확한 크기 여야한다고 생각했습니다.
xav

여러 열 행에 대한 데이터 프레임에서도 작동합니다. fillna의 기능은 매우 유용합니다.
Wertikal

19

당신은 할 수 있습니다

df.Cat1 = np.where(df.Cat1.isnull(), df.Cat2, df.Cat1)

RHS의 전체 구조 pandas요리 책 의 삼항 패턴을 사용 합니다 (어쨌든 읽기에 비용 듭니다 ). 의 벡터 버전입니다 a? b: c.


이 문제에 사용한 해결책이 아니라 매우 흥미로운 패턴입니다! 감사!
xav

여러 열에 이것을 사용하는 방법이 있습니까? 예를 들어이 df에 cat1, cat2, cat3, cat4, cat5가 있고 cat5가 비어 있다고 가정 해 봅시다. cat1이 비어 있으면 cat2, cat2가 비어 있으면 cat3 등으로 cat5를 cat1의 값으로 채우는 방법이 있습니까?
user8322222

@ user8322222 나는 확실히 늦었지만 누군가 가이 질문을 가지고 있다면, 당신은 excel cell = np.where (cond, val_true, np.where (cond, val_true, val_false)에서하는 것처럼 중첩 된 np.where를 할 수 있습니다. ).
Kaisar

이것이 pandas builtin을 재정의한다는 것을 언급하고 싶습니다 pd.DataFrame.fillna(). 그리고 코너 케이스 동작이 다를 수 있다고 생각합니다. 예를 들어 다른 데이터 프레임에서 일치하지 않는 시리즈 길이의 경우 : dfA [ 'Cat1'], dfB [ 'Cat2']
smci

8

value대신 매개 변수를 사용하십시오 method.

In [20]: df
Out[20]:
  Cat1      Cat2  Day
0  cat     mouse    1
1  dog  elephant    2
2  cat     giraf    3
3  NaN       ant    4

In [21]: df.Cat1 = df.Cat1.fillna(value=df.Cat2)

In [22]: df
Out[22]:
  Cat1      Cat2  Day
0  cat     mouse    1
1  dog  elephant    2
2  cat     giraf    3
3  ant       ant    4

답변 해주셔서 감사합니다! joris가 설명하는 방법보다는 가치를 사용하는 것이 무엇을 변경합니까?
xav

@xav value가 첫 번째 매개 변수이므로 joris는 실제로 똑같은 일을하고 있습니다. 그가 말했듯이 문서를 참조하십시오 .
chrisaycock

예, method처음에 나열된 대로 독 스트링은 약간 오해의 소지 가 있습니다.
joris

7

pandas.DataFrame.combine_first 도 작동합니다.

( 주의 : "결과 색인 열은 각 색인과 열의 합집합이됩니다"이므로 색인과 열이 일치하는지 확인해야합니다. )

import numpy as np
import pandas as pd
df = pd.DataFrame([["1","cat","mouse"],
    ["2","dog","elephant"],
    ["3","cat","giraf"],
    ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"])

In: df["Cat1"].combine_first(df["Cat2"])
Out: 
0    cat
1    dog
2    cat
3    ant
Name: Cat1, dtype: object

다른 답변과 비교 :

%timeit df["Cat1"].combine_first(df["Cat2"])
181 µs ± 11.3 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit df['Cat1'].fillna(df['Cat2'])
253 µs ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.where(df.Cat1.isnull(), df.Cat2, df.Cat1)
88.1 µs ± 793 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

아래에서는이 방법을 사용하지 않았습니다.

def is_missing(Cat1,Cat2):    
    if np.isnan(Cat1):        
        return Cat2
    else:
        return Cat1

df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)

예외가 발생하기 때문입니다.

TypeError: ("ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''", 'occurred at index 0')

즉, np.isnan은 기본 dtype (예 : np.float64)의 NumPy 배열에 적용될 수 있지만 객체 배열에 적용될 때 TypeError를 발생 시킵니다.

그래서 방법을 수정합니다.

def is_missing(Cat1,Cat2):    
    if pd.isnull(Cat1):        
        return Cat2
    else:
        return Cat1

%timeit df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)
701 µs ± 7.38 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

0

다음은보다 일반적인 접근 방식입니다 (fillna 방법이 아마도 더 좋을 것입니다).

def is_missing(Cat1,Cat2):    
    if np.isnan(Cat1):        
        return Cat2
    else:
        return Cat1

df['Cat1'] = df.apply(lambda x: is_missing(x['Cat1'],x['Cat2']),axis=1)

0

나는 이것이 오래된 질문이라는 것을 알고 있지만 최근에 비슷한 일을 할 필요가있었습니다. 다음을 사용할 수있었습니다.

df = pd.DataFrame([["1","cat","mouse"],
    ["2","dog","elephant"],
    ["3","cat","giraf"],
    ["4",np.nan,"ant"]],columns=["Day","Cat1","Cat2"])

print(df)

  Day Cat1      Cat2
0   1  cat     mouse
1   2  dog  elephant
2   3  cat     giraf
3   4  NaN       ant

df1 = df.bfill(axis=1).iloc[:, 1]
df1 = df1.to_frame()
print(df1)

결과 :

  Cat1
0  cat
1  dog
2  cat
3  ant

이것이 누군가에게 도움이되기를 바랍니다!

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