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ドキュメントを参照)。一致するインデックスでこれらの値を使用して、以下を埋めます。

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

7
いいね!それがfillnaシリーズになるとは知りませんでした。
アミタボリー2015年

1
ありがとう!セリエはNA値の数の正確なサイズでなければならないと思いました。
xav 2015年

複数列の行のデータフレームでも機能します。fillnaのその機能は非常に役立ちます。
Wertikal

19

あなたができる

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

RHSの全体的な構成ではpandasクックブックの3値パターンを使用します(いずれの場合も読むのにお金がかかります)。のベクター版ですa? b: c


私がこの問題に使用した解決策ではありませんが、非常に興味深いパターンです!ありがとう!
xav 2015年

これを複数の列に使用する方法はありますか?たとえば、このdfにcat1、cat2、cat3、cat4、cat5があり、cat5が空だったとします。cat1が空の場合はcat2、cat2が空の場合はcat3など、cat5にcat1の値を入力する方法はありますか?
user83222 2219

@ user8322222私は間違いなく遅れていますが、誰かがこの質問をしている場合は、Excelセル= np.where(cond、val_true、np.where(cond、val_true、val_false)、 )。
カイザー

これは、組み込みのパンダを再定義しているだけであることに言及したいと思い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 2015年

@xavvalueは最初のパラメーターであるため、jorisは実際にはまったく同じことを行っています。彼が言ったように、ドキュメントを参照してください。
chrisaycock 2015年

はい、method最初にリストされているように、docstringは少し誤解を招く可能性があります。
joris 2015年

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のNumPy配列(np.float64など)に適用できますがオブジェクト配列に適用すると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.