NaN'leri pandalar DataFrame'deki önceki değerlerle nasıl değiştirebilirim?


142

Bazı URL'leri içeren bir DataFrame'im olduğunu varsayalım NaN:

>>> import pandas as pd
>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN NaN   9

Yapmam gereken her şeyi, üstündeki aynı sütundaki NaNilk NaNdeğer olmayanla değiştirmek . İlk satırın hiçbir zaman a içermeyeceği varsayılır NaN. Dolayısıyla, önceki örnek için sonuç şöyle olacaktır:

   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

DataFrame'in tamamında sütun-sütun, öğe-öğe dolaşabilir ve değerleri doğrudan ayarlayabilirim, ancak bunu elde etmenin kolay (optimal olarak döngü içermeyen) bir yolu var mı?

Yanıtlar:


215

fillnaYöntemi DataFrame üzerinde kullanabilir ve yöntemi şu şekilde belirtebilirsiniz ffill(ileriye doğru doldurma):

>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df.fillna(method='ffill')
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

Bu method...

son geçerli gözlemi bir sonraki geçerliye ilerle

Tersine gitmek için bir bfillyöntem de var .

Bu yöntem, DataFrame'i yerinde değiştirmez - döndürülen DataFrame'i bir değişkene yeniden bağlamanız veya başka bir şekilde belirtmeniz gerekir inplace=True:

df.fillna(method='ffill', inplace=True)

Ya boş hücre sütun adları dizinindeyse (yani, birkaç sütunun adı yoktu, ancak verileri vardı. Boş sütun dizin hücresini içindeki hücreyle doldurmak için bfill veya ffill kullanmanın bir yolu var mı? hemen altındaki satır? Örneğin: df = pd.DataFrame ({'col1': [2, 4, 8], 'col2': [2, 0, 0], '': [10, 2, 1]} , index = ['falcon', 'dog', 'spider' ']) Üçüncü sütunun adını 10 olarak değiştirmek için bfill veya ffill'i nasıl kullanabilirim (bu, boş üçüncü sütun adının hemen altındaki satırın değeridir) ? Teşekkürler!
GbG

31

Kabul edilen cevap mükemmel. İlişkili ama biraz farklı bir durumum vardı, ileriye doğru doldurmam gerekiyordu, ancak sadece gruplar içinde. Birisinin de aynı ihtiyacı olması durumunda, fillna'nın bir DataFrameGroupBy nesnesi üzerinde çalıştığını bilin.

>>> example = pd.DataFrame({'number':[0,1,2,nan,4,nan,6,7,8,9],'name':list('aaabbbcccc')})
>>> example
  name  number
0    a     0.0
1    a     1.0
2    a     2.0
3    b     NaN
4    b     4.0
5    b     NaN
6    c     6.0
7    c     7.0
8    c     8.0
9    c     9.0
>>> example.groupby('name')['number'].fillna(method='ffill') # fill in row 5 but not row 3
0    0.0
1    1.0
2    2.0
3    NaN
4    4.0
5    4.0
6    6.0
7    7.0
8    8.0
9    9.0
Name: number, dtype: float64

tam olarak aradığım şey, ty
Tony

18

Seçeneği pandas.DataFrame.fillnaile kullanabilirsiniz method='ffill'. 'ffill'"ileriye doğru doldurma" anlamına gelir ve son geçerli gözlemi ileriye doğru yayacaktır. Alternatif, 'bfill'aynı şekilde, ancak geriye doğru işleyen şeydir.

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
df = df.fillna(method='ffill')

print(df)
#   0  1  2
#0  1  2  3
#1  4  2  3
#2  4  2  9

pandas.DataFrame.ffillİşleri daha basit hale getirmek için bunun için doğrudan bir eşanlamlılık işlevi de vardır .


14

Bu çözümü denerken fark ettiğim bir şey, dizinin başında veya sonunda N / A varsa, ffill ve bfill'in pek işe yaramadığıdır. İkisine de ihtiyacınız var.

In [224]: df = pd.DataFrame([None, 1, 2, 3, None, 4, 5, 6, None])

In [225]: df.ffill()
Out[225]:
     0
0  NaN
1  1.0
...
7  6.0
8  6.0

In [226]: df.bfill()
Out[226]:
     0
0  1.0
1  1.0
...
7  6.0
8  NaN

In [227]: df.bfill().ffill()
Out[227]:
     0
0  1.0
1  1.0
...
7  6.0
8  6.0

Parlak. Sorunum için tam olarak buna ihtiyacım vardı. Hem öncesi hem de sonrası doldurma. Çok teşekkürler.
Prometheus

Harika. Bu çözüme ihtiyacım var. Teşekkürler
Junkrat


5

Sadece bir sütunlu versiyon

  • NAN'ı son geçerli değerle doldurun
df[column_name].fillna(method='ffill', inplace=True)
  • NAN'ı sonraki geçerli değerle doldurun
df[column_name].fillna(method='backfill', inplace=True)

5

Sadece ffillyönteme katılıyorum , ancak fazladan bir bilgi, ileri doldurmayı anahtar kelime argümanıyla sınırlayabilmenizdir limit.

>>> import pandas as pd    
>>> df = pd.DataFrame([[1, 2, 3], [None, None, 6], [None, None, 9]])

>>> df
     0    1   2
0  1.0  2.0   3
1  NaN  NaN   6
2  NaN  NaN   9

>>> df[1].fillna(method='ffill', inplace=True)
>>> df
     0    1    2
0  1.0  2.0    3
1  NaN  2.0    6
2  NaN  2.0    9

Şimdi limitanahtar kelime bağımsız değişkeniyle

>>> df[0].fillna(method='ffill', limit=1, inplace=True)

>>> df
     0    1  2
0  1.0  2.0  3
1  1.0  2.0  6
2  NaN  2.0  9

1

Benim durumumda, farklı cihazlardan zaman serilerimiz var ama bazı cihazlar bir süre boyunca herhangi bir değer gönderemedi. Bu yüzden her cihaz ve zaman periyodu için NA değerleri oluşturmalı ve bundan sonra da fillna yapmalıyız.

df = pd.DataFrame([["device1", 1, 'first val of device1'], ["device2", 2, 'first val of device2'], ["device3", 3, 'first val of device3']])
df.pivot(index=1, columns=0, values=2).fillna(method='ffill').unstack().reset_index(name='value')

Sonuç:

        0   1   value
0   device1     1   first val of device1
1   device1     2   first val of device1
2   device1     3   first val of device1
3   device2     1   None
4   device2     2   first val of device2
5   device2     3   first val of device2
6   device3     1   None
7   device3     2   None
8   device3     3   first val of device3

0

fillnaNaN değerlerini kaldırmak veya değiştirmek için kullanabilirsiniz .

NaN Kaldır

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])

df.fillna(method='ffill')
     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

NaN Değiştir

df.fillna(0) # 0 means What Value you want to replace 
     0    1    2
0  1.0  2.0  3.0
1  4.0  0.0  0.0
2  0.0  0.0  9.0

Referans pandas.DataFrame.fillna

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.