Pandas fillna () 'ya bağımsız değişken olarak başka bir sütunun tamamı nasıl iletilir


94

fillnaYöntem kullanarak bir sütundaki eksik değerleri başka bir sütundaki değerlerle doldurmak istiyorum .

(Her satırda döngü yapmanın çok kötü bir uygulama olacağını ve her şeyi tek seferde yapmanın daha iyi olacağını okudum ama bunu nasıl yapacağımı bulamadım fillna.)

Önceki veriler:

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

Sonraki veriler:

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

Yanıtlar:


173

Bu sütunu aşağıdakilere sağlayabilirsiniz fillna( dokümanlara bakın ), bu değerleri doldurmak için eşleşen dizinlerde kullanır:

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

7
Güzel! Bunun fillnabir dizi sürdüğünü bilmiyordum .
Ami Tavory

1
Teşekkürler! Serinin NA değerlerinin sayısının tam boyutu olması gerektiğini düşündüm.
xav

Çok sütunlu satırlar için veri çerçeveleri için de çalışır. Fillna'nın bu özelliği çok faydalıdır.
Wertikal

19

Yapabilirsin

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

RHS üzerindeki genel yapı , pandasyemek kitabındaki üçlü modeli kullanır (her durumda okumak için ödeme yapar). Bu bir vektör versiyonu a? b: c.


Bu problem için kullandığım çözüm değil ama çok ilginç model! Teşekkürler!
xav

bunu birden çok sütun için kullanmanın bir yolu var mı? örneğin, bu df'de cat1, cat2, cat3, cat4, cat5 varsa ve diyelim ki cat5 boştur. cat5'i cat1'den gelen değerlerle doldurmanın bir yolu eğer cat1 boşsa cat2, cat2 boşsa cat3 vb. olabilir mi?
user8322222

@ user8322222 Kesinlikle geç kaldım ama bu soruyu soran biri varsa, tıpkı excel cell = np.where (koşul, val_true, np.where (koşul, val_true, val_false) 'de yaptığınız gibi np.where iç içe geçebilirsiniz. ).
Kaisar

Bunun sadece pandaların yerleşimini yeniden tanımladığını belirtmek istersiniz pd.DataFrame.fillna(). Ve köşe durumu davranışının farklı veri çerçevelerinden farklı seri uzunlukları için farklı olabileceğinden şüpheleniyorum: dfA ['Cat1'], dfB ['Cat2']
smci

8

Bunun valueyerine parametreyi kullanın 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

Cevap için teşekkürler! Joris'in tarif ettiği yöntem yerine değeri kullanmak neyi değiştirir?
xav

@xav valueilk parametredir, bu nedenle joris aslında aynı şeyi yapıyor. Dediği gibi, belgelere bakın .
chrisaycock

Evet, docstring biraz yanıltıcıdır. method ilk önce listelendiği .
joris

7

pandas.DataFrame.combine_first de çalışır.

( Dikkat: "Sonuç dizini sütunları, ilgili dizinlerin ve sütunların birleşimi olacağından", dizin ve sütunların eşleşip eşleşmediğini kontrol etmelisiniz. )

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

Diğer yanıtlarla karşılaştırın:

%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)

Aşağıdaki bu yöntemi kullanmadım:

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)

çünkü bir İstisna yaratacaktır:

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')

bu, np.isnan'ın yerel dtype (np.float64 gibi) NumPy dizilerine uygulanabileceği, ancak nesne dizilerine uygulandığında TypeError'ı yükselttiği anlamına gelir .

Bu yüzden yöntemi revize ediyorum:

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

İşte daha genel bir yaklaşım (fillna yöntemi muhtemelen daha iyidir)

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

Bunun eski bir soru olduğunu biliyorum, ancak son zamanlarda benzer bir şey yapmaya ihtiyacım vardı. Aşağıdakileri kullanabildim:

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)

Hangi sonuç:

  Cat1
0  cat
1  dog
2  cat
3  ant

Umarım bu birine yardımcı olur!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.