簡體   English   中英

在 Python Pandas 中的多列中填充

[英]Fillna in multiple columns in place in Python Pandas

我有一個混合類型的熊貓數據框,有些是字符串,有些是數字。 我想將字符串列中的 NAN 值替換為“。”,並將浮點列中的 NAN 值替換為 0。

考慮這個虛構的小例子:

df = pd.DataFrame({'Name':['Jack','Sue',pd.np.nan,'Bob','Alice','John'],
    'A': [1, 2.1, pd.np.nan, 4.7, 5.6, 6.8],
    'B': [.25, pd.np.nan, pd.np.nan, 4, 12.2, 14.4],
    'City':['Seattle','SF','LA','OC',pd.np.nan,pd.np.nan]})

現在,我可以用 3 行來完成:

df['Name'].fillna('.',inplace=True)
df['City'].fillna('.',inplace=True)
df.fillna(0,inplace=True)

由於這是一個小數據框,因此 3 行可能就可以了。 在我的真實示例中(由於數據機密性原因,我無法在此分享),我有更多的字符串列和數字列。 所以我最終只為fillna寫了很多行。 有沒有一種簡潔的方法來做到這一點?

在尋找此問題的答案時遇到此頁面,但不喜歡現有答案。 我最終在DataFrame.fillna 文檔中找到了更好的東西,並認為我會為發生這種情況的其他人做出貢獻。

如果您有多個列,但只想替換其中一部分中的NaN ,則可以使用:

df.fillna({'Name':'.', 'City':'.'}, inplace=True)

這還允許您為每列指定不同的替換。 如果你想繼續填充所有剩余的NaN值,你可以在最后拋出另一個fillna

df.fillna({'Name':'.', 'City':'.'}, inplace=True).fillna(0, inplace=True)

編輯(2021 年 4 月 22 日)

自原始帖子以來,功能(可能/顯然)發生了變化,您不能再鏈接 2 個inplace fillna()操作。 您仍然可以鏈接,但現在必須將該鏈分配給df而不是就地修改,例如:

df = df.fillna({'Name':'.', 'City':'.'}).fillna(0)

您可以通過檢查dtype.kind檢查dtype是否為numericapply您的列:

res = df.apply(lambda x: x.fillna(0) if x.dtype.kind in 'biufc' else x.fillna('.'))

print(res)
     A      B     City   Name
0  1.0   0.25  Seattle   Jack
1  2.1   0.00       SF    Sue
2  0.0   0.00       LA      .
3  4.7   4.00       OC    Bob
4  5.6  12.20        .  Alice
5  6.8  14.40        .   John

您可以手動列出字符串列,也可以從df.dtypes中收集它們。 獲得字符串/對象列的列表后,您可以一次在所有這些列上調用fillna

# str_cols = ['Name','City']
str_cols = df.columns[df.dtypes==object]
df[str_cols] = df[str_cols].fillna('.')
df = df.fillna(0)

定義一個函數:

def myfillna(series):
    if series.dtype is pd.np.dtype(float):
        return series.fillna(0)
    elif series.dtype is pd.np.dtype(object):
        return series.fillna('.')
    else:
        return series

如果您想以其他方式填充不同 dtype 的列,您可以添加其他 elif 語句。 現在將此函數應用於數據框的所有列

df = df.apply(myfillna)

這與“就地”相同

有一種更簡單的方法,可以在一行中完成:

df.fillna({'Name':0,'City':0},inplace=True)

這不是一個了不起的改進,但如果你將它乘以 100,只寫列名 + ':0' 比復制和粘貼所有內容 100 次要快得多。

如果您想用相同的值(“v”)替換列列表(“lst”)

def nan_to_zero(df, lst, v):
    d = {x:v for x in lst}
    df.fillna(d, inplace=True)
    return df

如果您不想指定單獨的每列替換值,您可以這樣做:

df[['Name', 'City']].fillna('.',inplace=True)

如果你不喜歡就地(像我一樣)你可以這樣做:

columns = ['Name', 'City']
df[columns] = df[columns].fillna('.')

實現這一點的最簡潔易讀的方法是使用df.select_dtypes.columns ,尤其是對於許多列。 ( df.select_dtypes , df.columns )

df.select_dtypes返回一個新的df ,其中僅包含與您需要的 dtype 匹配的列。

df.columns返回df中的列名列表。

完整代碼:

float_column_names = df.select_dtypes(float).columns
df[float_column_names] = df[float_column_names].fillna(0)

string_column_names = df.select_dtypes(object).columns
df[string_column_names] df[string_column_names].fillna('.')

很簡單的方法是: dt.replace(pd.np.nan, "NA") 如果您想要其他替換,您應該使用下一個: dt.replace("pattern", "replaced by (new pattern)")

暫無
暫無

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

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