簡體   English   中英

如何在 Pandas 數據框的列中用零替換 NaN 值?

[英]How to replace NaN values by Zeroes in a column of a Pandas Dataframe?

我有一個熊貓數據框如下:

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

當我嘗試將函數應用於 Amount 列時,出現以下錯誤:

ValueError: cannot convert float NaN to integer

我嘗試使用數學模塊中的 .isnan 應用函數 我嘗試過 pandas .replace 屬性 我嘗試過 pandas 0.9 中的 .sparse 數據屬性 我也嘗試過 if NaN == NaN 函數中的語句。 我還看過這篇文章如何在 R 數據框中用零替換 NA 值? 在看其他一些文章的時候。 我嘗試過的所有方法都不起作用或無法識別 NaN。 任何提示或解決方案將不勝感激。

我相信DataFrame.fillna()會為您做到這一點。

鏈接到 Docs 以獲取dataframeSeries

例子:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

要僅將 NaN 填充在一列中,請僅選擇該列。 在這種情況下,我使用 inplace=True 來實際更改 df 的內容。

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

編輯:

要避免SettingWithCopyWarning ,請使用內置的特定於列的功能:

df.fillna({1:0}, inplace=True)

不能保證切片返回視圖或副本。 你可以做

df['column'] = df['column'].fillna(value)

您可以使用replaceNaN更改為0

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

下面的代碼對我有用。

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

我只是想提供一些更新/特殊情況,因為看起來人們仍然來到這里。 如果您使用多索引或以其他方式使用索引切片器,則 inplace=True 選項可能不足以更新您選擇的切片。 例如,在 2x2 級別的多索引中,這不會更改任何值(從 pandas 0.15 開始):

idx = pd.IndexSlice
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)

“問題”是鏈接破壞了 fillna 更新原始數據幀的能力。 我將“問題”放在引號中,因為設計決策有充分的理由導致在某些情況下不通過這些鏈進行解釋。 此外,這是一個復雜的示例(盡管我確實遇到過),但根據您的切片方式,這可能適用於較少級別的索引。

解決方案是 DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))

它是一行,讀起來相當好(有點),並消除了中間變量或循環的任何不必要的混亂,同時允許您將 fillna 應用於您喜歡的任何多級切片!

如果有人能找到這不起作用的地方,請在評論中發布,我一直在搞亂它並查看源代碼,它似乎至少解決了我的多索引切片問題。

您還可以使用字典來填充 DataFrame 中特定列的 NaN 值,而不是用一些 oneValue 填充所有 DF。

import pandas as pd

df = pd.read_excel('example.xlsx')
df.fillna( {
        'column1': 'Write your values here',
        'column2': 'Write your values here',
        'column3': 'Write your values here',
        'column4': 'Write your values here',
        .
        .
        .
        'column-n': 'Write your values here'} , inplace=True)

填充缺失值的簡單方法:-

填充字符串列:當字符串列有缺失值和 NaN 值時。

df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)

填充數字列:當數字列有缺失值和 NaN 值時。

df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)

用零填充 NaN:

df['column name'].fillna(0, inplace = True)

替換 pandas 中的 na 值

df['column_name'].fillna(value_to_be_replaced,inplace=True)

如果inplace = False ,它將返回修改后的值,而不是更新 df (數據框)。

在此處輸入圖像描述

考慮到上表中的特定列Amount是整數類型。 以下將是一個解決方案:

df['Amount'] = df.Amount.fillna(0).astype(int)

同樣,您可以使用各種數據類型填充它,例如floatstr等。

特別是,我會考慮數據類型來比較同一列的各種值。

用不同的方式替換不同列中的 nan:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)

將所有 nan 替換為 0

df = df.fillna(0)

已經有很多貢獻了,但由於我是新來的,我仍然會提供意見。

在 Pandas DataFrame 中有兩種方法可以用零替換NaN值:

  1. fillna():函數使用指定的方法填充 NA/NaN 值。
  2. replace(): df.replace() 一個簡單的方法,用於替換字符串、正則表達式、列表、字典

例子:

#NaN with zero on all columns
df2 = df.fillna(0)


#Using the inplace=True keyword in a pandas method changes the default behaviour.
    df.fillna(0, inplace = True)

# multiple columns appraoch
df[["Student", "ID"]] = df[["Student", "ID"]].fillna(0)

最后是 replace() 方法:

df["Student"] = df["Student"].replace(np.nan, 0)

這對我有用,但沒有人提到它。 會不會有什么問題?

df.loc[df['column_name'].isnull(), 'column_name'] = 0

如果要將其轉換為 pandas 數據框,也可以使用fillna來完成。

import numpy as np
df=np.array([[1,2,3, np.nan]])

import pandas as pd
df=pd.DataFrame(df)
df.fillna(0)

這將返回以下內容:

     0    1    2   3
0  1.0  2.0  3.0 NaN
>>> df.fillna(0)
     0    1    2    3
0  1.0  2.0  3.0  0.0

主要有兩種選擇; 如果僅用數字替換(跨列)填充或填充缺失值NaN / np.nan

df['Amount'].fillna(value=None, method= ,axis=1,)就足夠了:

從文檔:

value : 標量、dict、Series 或 DataFrame 用於填充孔的值(例如 0),或者是一個 dict/Series/DataFrame 值,指定用於每個索引(對於 Series)或列(對於 DataFrame)的值. (不在 dict/Series/DataFrame 中的值將不會被填充)。 此值不能是列表。

這意味着不再允許估算“字符串”或“常量”。

對於更專業的估算,請使用SimpleImputer()

from sklearn.impute import SimpleImputer
si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])

如果要為特定列填充 NaN,可以使用 loc:

d1 = {"Col1" : ['A', 'B', 'C'],
     "fruits": ['Avocado', 'Banana', 'NaN']}
d1= pd.DataFrame(d1)

output:

Col1    fruits
0   A   Avocado
1   B   Banana
2   C   NaN


d1.loc[ d1.Col1=='C', 'fruits' ] =  'Carrot'


output:

Col1    fruits
0   A   Avocado
1   B   Banana
2   C   Carrot

我覺得也值得一提,解釋一下fillna()的參數配置,比如Method、Axis、Limit等。

從我們擁有的文檔中:

Series.fillna(value=None, method=None, axis=None, 
                 inplace=False, limit=None, downcast=None)
Fill NA/NaN values using the specified method.

參數

value [scalar, dict, Series, or DataFrame] Value to use to 
 fill holes (e.g. 0), alternately a dict/Series/DataFrame 
 of values specifying which value to use for each index 
 (for a Series) or column (for a DataFrame). Values not in 
 the dict/Series/DataFrame will not be filled. This 
 value cannot be a list.

method [{‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, 
 default None] Method to use for filling holes in 
 reindexed Series pad / ffill: propagate last valid 
 observation forward to next valid backfill / bfill: 
 use next valid observation to fill gap axis 
 [{0 or ‘index’}] Axis along which to fill missing values.

inplace [bool, default False] If True, fill 
 in-place. Note: this will modify any other views
 on this object (e.g., a no-copy slice for a 
 column in a DataFrame).

limit [int,defaultNone] If method is specified, 
 this is the maximum number of consecutive NaN 
 values to forward/backward fill. In other words, 
 if there is a gap with more than this number of 
 consecutive NaNs, it will only be partially filled. 
 If method is not specified, this is the maximum 
 number of entries along the entire axis where NaNs
 will be filled. Must be greater than 0 if not None.

downcast [dict, default is None] A dict of item->dtype 
 of what to downcast if possible, or the string ‘infer’ 
 which will try to downcast to an appropriate equal 
 type (e.g. float64 to int64 if possible).

好的。 讓我們從method=參數開始,它有前向填充(ffill)和后向填充(bfill) ffill 正在向前復制前一個非缺失值。

例如:

import pandas as pd
import numpy as np
inp = [{'c1':10, 'c2':np.nan, 'c3':200}, {'c1':np.nan,'c2':110, 'c3':210}, {'c1':12,'c2':np.nan, 'c3':220},{'c1':12,'c2':130, 'c3':np.nan},{'c1':12,'c2':np.nan, 'c3':240}]
df = pd.DataFrame(inp)

  c1       c2      c3
0   10.0     NaN      200.0
1   NaN   110.0 210.0
2   12.0     NaN      220.0
3   12.0     130.0 NaN
4   12.0     NaN      240.0

前向填充:

df.fillna(method="ffill")

    c1     c2      c3
0   10.0      NaN 200.0
1   10.0    110.0   210.0
2   12.0    110.0   220.0
3   12.0    130.0   220.0
4   12.0    130.0   240.0

向后填充:

df.fillna(method="bfill")

    c1      c2     c3
0   10.0    110.0   200.0
1   12.0    110.0   210.0
2   12.0    130.0   220.0
3   12.0    130.0   240.0
4   12.0      NaN   240.0

Axis Parameter 幫助我們選擇填充的方向:

填寫方向:

填充:

Axis = 1 
Method = 'ffill'
----------->
  direction 

df.fillna(method="ffill", axis=1)

       c1   c2      c3
0   10.0     10.0   200.0
1    NaN    110.0   210.0
2   12.0     12.0   220.0
3   12.0    130.0   130.0
4   12.0    12.0    240.0

Axis = 0 # by default 
Method = 'ffill'
|
|       # direction 
|
V
e.g: # This is the ffill default
df.fillna(method="ffill", axis=0)

    c1     c2      c3
0   10.0      NaN   200.0
1   10.0    110.0   210.0
2   12.0    110.0   220.0
3   12.0    130.0   220.0
4   12.0    130.0   240.0

填充:

axis= 0
method = 'bfill'
^
|
|
|
df.fillna(method="bfill", axis=0)

    c1     c2      c3
0   10.0    110.0   200.0
1   12.0    110.0   210.0
2   12.0    130.0   220.0
3   12.0    130.0   240.0
4   12.0      NaN   240.0

axis = 1
method = 'bfill'
<-----------
df.fillna(method="bfill", axis=1)
        c1     c2       c3
0    10.0   200.0   200.0
1   110.0   110.0   210.0
2    12.0   220.0   220.0
3    12.0   130.0     NaN
4    12.0   240.0   240.0

# alias:
#  'fill' == 'pad' 
#   bfill == backfill

限制參數:

df
    c1     c2      c3
0   10.0      NaN   200.0
1    NaN    110.0   210.0
2   12.0      NaN   220.0
3   12.0    130.0     NaN
4   12.0      NaN   240.0

僅替換跨列的第一個 NaN 元素:

df.fillna(value = 'Unavailable', limit=1)
            c1           c2          c3
0          10.0 Unavailable       200.0
1   Unavailable       110.0       210.0
2          12.0         NaN       220.0
3          12.0       130.0 Unavailable
4          12.0         NaN       240.0

df.fillna(value = 'Unavailable', limit=2)

           c1            c2          c3
0          10.0 Unavailable       200.0
1   Unavailable       110.0       210.0
2          12.0 Unavailable       220.0
3          12.0       130.0 Unavailable
4          12.0         NaN       240.0

向下轉換參數:

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   c1      4 non-null      float64
 1   c2      2 non-null      float64
 2   c3      4 non-null      float64
dtypes: float64(3)
memory usage: 248.0 bytes

df.fillna(method="ffill",downcast='infer').info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   c1      5 non-null      int64  
 1   c2      4 non-null      float64
 2   c3      5 non-null      int64  
dtypes: float64(1), int64(2)
memory usage: 248.0 bytes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM