Làm cách nào tôi có thể thay thế tất cả các giá trị NaN bằng Zeros trong một cột của khung dữ liệu gấu trúc


457

Tôi có một khung dữ liệu như dưới đây

      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

Khi tôi cố gắng .apply một hàm vào cột Số tiền, tôi gặp lỗi sau.

ValueError: cannot convert float NaN to integer

Tôi đã thử áp dụng một hàm bằng cách sử dụng .isnan từ Mô-đun Toán học Tôi đã thử thuộc tính pandas .replace Tôi đã thử thuộc tính dữ liệu .spzzy từ gấu trúc 0.9 Tôi cũng đã thử nếu câu lệnh NaN == NaN trong một hàm. Tôi cũng đã xem bài viết này Làm cách nào để thay thế các giá trị NA bằng các số 0 trong khung dữ liệu R? Trong khi nhìn vào một số bài viết khác. Tất cả các phương pháp tôi đã thử không hoạt động hoặc không nhận ra NaN. Bất kỳ gợi ý hoặc giải pháp sẽ được đánh giá cao.


Vấn đề duy nhất là df.fill.na () không hoạt động nếu khung dữ liệu mà bạn đang áp dụng nó được ghép lại hoặc bị cắt qua chức năng loc
Prince Agarwal

Câu trả lời:


754

Tôi tin rằng DataFrame.fillna()sẽ làm điều này cho bạn.

Liên kết đến Docs cho một khung dữ liệu và cho một Series .

Thí dụ:

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

Để điền vào NaN chỉ trong một cột, chỉ chọn cột đó. trong trường hợp này tôi đang sử dụng inplace = True để thực sự thay đổi nội dung của 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

BIÊN TẬP:

Để tránh a SettingWithCopyWarning, hãy sử dụng chức năng dành riêng cho cột:

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

1
Có đảm bảo rằng đó df[1]là một chế độ xem chứ không phải là bản sao của DF gốc? Rõ ràng, nếu có một tình huống hiếm hoi là bản sao, nó sẽ gây ra một lỗi cực kỳ rắc rối. Có một tuyên bố rõ ràng về điều đó trong tài liệu gấu trúc?
tối đa

@max Xem điều này, có thể giải quyết câu hỏi của bạn: stackoverflow.com/questions/23296282/NH
Aman

Cảm ơn. Hiểu biết của tôi có đúng không khi trong câu trả lời đó, "bộ chỉ mục đặt" là hoạt động lập chỉ mục ngoài cùng (được thực hiện ngay trước khi gán. Vì vậy, bất kỳ nhiệm vụ nào chỉ sử dụng một bộ chỉ mục duy nhất đều được đảm bảo an toàn, làm cho mã của bạn an toàn?
tối đa

1
Tại sao điều này không làm việc cho tôi? xem: stackoverflow.com/questions/39452095/how-to-fillna-with-value-0
hiển thị

1
ví dụ cuối cùng ném thiết lậpWithCopyWarning
Sip

124

Nó không được đảm bảo rằng lát cắt trả về một khung nhìn hoặc một bản sao. Bạn có thể làm

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

14
Chỉ cần phát hiện ra vấn đề "inplace = True". Câu trả lời này tránh được vấn đề và tôi nghĩ là giải pháp sạch nhất được trình bày.
TimCera

48

Bạn có thể sử dụng replaceđể thay đổi NaNthành 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)

Nó sẽ chỉ thay thế NaN? hoặc nó cũng sẽ thay thế giá trị ở đâu NAhoặc NaNnhư thế df.fillna(0)nào? Tôi đang tìm giải pháp chỉ thay thế giá trị ở nơi có NaNvà khôngNA
Shyam Bhimani

1
@ShyamBhimani chỉ nên thay thế NaNcác giá trị np.isnanlà True
Anton Protopopov

23

Tôi chỉ muốn cung cấp một chút cập nhật / trường hợp đặc biệt vì có vẻ như mọi người vẫn đến đây. Nếu bạn đang sử dụng đa chỉ mục hoặc bằng cách khác sử dụng bộ cắt chỉ mục, tùy chọn inplace = True có thể không đủ để cập nhật lát cắt bạn đã chọn. Ví dụ: trong đa chỉ mục cấp độ 2x2, điều này sẽ không thay đổi bất kỳ giá trị nào (kể từ gấu trúc 0,15):

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

"Vấn đề" là chuỗi kết nối phá vỡ khả năng fillna để cập nhật khung dữ liệu gốc. Tôi đặt "vấn đề" trong dấu ngoặc kép vì có những lý do chính đáng cho các quyết định thiết kế dẫn đến việc không diễn giải qua các chuỗi này trong một số tình huống nhất định. Ngoài ra, đây là một ví dụ phức tạp (mặc dù tôi thực sự gặp phải nó), nhưng điều tương tự có thể áp dụng cho các cấp chỉ mục ít hơn tùy thuộc vào cách bạn cắt.

Giải pháp là DataFrame.update:

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

Đó là một dòng, đọc hợp lý (loại) và loại bỏ bất kỳ sự lộn xộn không cần thiết nào với các biến hoặc vòng lặp trung gian trong khi cho phép bạn áp dụng fillna cho bất kỳ lát cắt đa cấp nào bạn muốn!

Nếu bất cứ ai có thể tìm thấy những nơi này không hoạt động, xin vui lòng gửi trong các bình luận, tôi đã nhầm lẫn với nó và xem nguồn và nó dường như giải quyết ít nhất các vấn đề lát cắt đa chỉ số của tôi.


21

Các mã dưới đây làm việc cho tôi.

import pandas

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

df = df.fillna(0)

7

Cách dễ dàng để điền vào các giá trị còn thiếu: -

điền cột cột: khi cột chuỗi thiếu giá trị và giá trị NaN.

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

điền vào các cột số: khi các cột số có giá trị thiếu và giá trị NaN.

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

làm đầy NaN bằng 0:

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

5

Bạn cũng có thể sử dụng từ điển để điền vào các giá trị NaN của các cột cụ thể trong DataFrame thay vì điền vào tất cả DF với một số giá trị.

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)

Đây là giải pháp dành cho nhà phát triển dành cho câu hỏi của OP.
johnDanger

4

nhập mô tả hình ảnh ở đây

Xem xét cột cụ thể Amounttrong bảng trên là loại số nguyên. Sau đây sẽ là một giải pháp:

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

Tương tự, bạn có thể điền nó với nhiều loại dữ liệu khác nhau float, strv.v.

Cụ thể, tôi sẽ xem xét kiểu dữ liệu để so sánh các giá trị khác nhau của cùng một cột.


2

Để thay thế giá trị na trong gấu trúc

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

nếu inplace = False, thay vì cập nhật df (khung dữ liệu), nó sẽ trả về các giá trị được sửa đổi.


1

Nếu bạn đã chuyển đổi nó thành một khung dữ liệu gấu trúc, bạn cũng có thể thực hiện điều này bằng cách sử dụng fillna.

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

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

Điều này sẽ trả về như sau:

     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

1

Có hai lựa chọn có sẵn là chủ yếu; trong trường hợp cắt bỏ hoặc điền các giá trị bị thiếu NaN / np.nan chỉ bằng các thay thế bằng số (trên các cột:

df['Amount'].fillna(value=None, method= ,axis=1,) là đủ:

Từ Tài liệu:

giá trị: vô hướng, dict, Sê-ri hoặc Giá trị khung dữ liệu sẽ sử dụng để lấp lỗ hổng (ví dụ 0), xen kẽ một dict / Series / DataFrame của các giá trị chỉ định giá trị nào sẽ sử dụng cho mỗi chỉ mục (cho Sê-ri) hoặc cột (cho DataFrame) . (các giá trị không nằm trong dict / Series / DataFrame sẽ không được điền). Giá trị này không thể là một danh sách.

Điều đó có nghĩa là 'chuỗi' hoặc 'hằng số' không còn được phép bị từ chối.

Để biết thêm chi tiết chuyên môn, hãy sử dụng 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']])

0

Để thay thế nan trong các cột khác nhau bằng các cách khác nhau:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.