Tìm chỉ số nguyên của các hàng có NaN trong khung dữ liệu gấu trúc


94

Tôi có một con gấu trúc DataFrame như thế này:

                    a         b
2011-01-01 00:00:00 1.883381  -0.416629
2011-01-01 01:00:00 0.149948  -1.782170
2011-01-01 02:00:00 -0.407604 0.314168
2011-01-01 03:00:00 1.452354  NaN
2011-01-01 04:00:00 -1.224869 -0.947457
2011-01-01 05:00:00 0.498326  0.070416
2011-01-01 06:00:00 0.401665  NaN
2011-01-01 07:00:00 -0.019766 0.533641
2011-01-01 08:00:00 -1.101303 -1.408561
2011-01-01 09:00:00 1.671795  -0.764629

Có cách nào hiệu quả để tìm chỉ số "số nguyên" của các hàng có NaN không? Trong trường hợp này, đầu ra mong muốn phải là [3, 6].


12
Nếu bạn chỉ muốn chọn các hàng có nan, bạn có thể thực hiệndf[np.isnan(df['b'])]
lazy 1

4
Theo dõi từ @ lazy1 - thay vì sử dụng numpyisnanbạn cũng có thể sử dụngdf['b'].isnull()
jmetz

Câu trả lời:


46

Đối với DataFrame df:

import numpy as np
index = df['b'].index[df['b'].apply(np.isnan)]

sẽ trả lại cho bạn cái MultiIndexmà bạn có thể sử dụng để lập chỉ mục trở lại df, ví dụ:

df['a'].ix[index[0]]
>>> 1.452354

Đối với chỉ số số nguyên:

df_index = df.index.values.tolist()
[df_index.index(i) for i in index]
>>> [3, 6]

1
Như trực quan như ixâm thanh, đối với một số lý do có vẻ như nó đã được tán thành ủng hộiloc
thảo quả

145

Đây là một giải pháp đơn giản hơn:

inds = pd.isnull(df).any(1).nonzero()[0]

In [9]: df
Out[9]: 
          0         1
0  0.450319  0.062595
1 -0.673058  0.156073
2 -0.871179 -0.118575
3  0.594188       NaN
4 -1.017903 -0.484744
5  0.860375  0.239265
6 -0.640070       NaN
7 -0.535802  1.632932
8  0.876523 -0.153634
9 -0.686914  0.131185

In [10]: pd.isnull(df).any(1).nonzero()[0]
Out[10]: array([3, 6])

29
Tôi đã kết thúc bằng cách sử dụng này:np.where(df['b'].notnull())[0]

cảm ơn, .nonzero()[0]còn tốt hơn [i for i, k in enumerate(mask) if k].)
Winand

2
Bạn có thể có thể đơn giản hóa điều này hơn nữa:r, _ = np.where(df.isna())
cs95

2
thêm .to_numpy()để chuyển đổi trong mảng numpy trước -pd.isnull(df).any(1).to_numpy().nonzero()
7bStan

13

Giải pháp một dòng. Tuy nhiên nó chỉ hoạt động cho một cột.

df.loc[pandas.isna(df["b"]), :].index

Đây là những gì tôi đang tìm kiếm. Tôi đã đưa nó vào danh sách bằng cách gói nó trong một cái list(...)giống như thế này:list(df.loc[pandas.isna(df["b"]), :].index)
Daniel Butler,

10

Và chỉ trong trường hợp, nếu bạn muốn tìm tọa độ của 'nan' cho tất cả các cột thay thế (giả sử chúng đều là số), thì bạn vào đây:

df = pd.DataFrame([[0,1,3,4,np.nan,2],[3,5,6,np.nan,3,3]])

df
   0  1  2    3    4  5
0  0  1  3  4.0  NaN  2
1  3  5  6  NaN  3.0  3

np.where(np.asanyarray(np.isnan(df)))
(array([0, 1]), array([4, 3]))

9

Không biết điều này có quá muộn không nhưng bạn có thể sử dụng np.where để tìm các chỉ số không phải giá trị như:

indices = list(np.where(df['b'].isna()[0]))

4

Dưới đây là các thử nghiệm cho một số phương pháp:

%timeit np.where(np.isnan(df['b']))[0]
%timeit pd.isnull(df['b']).nonzero()[0]
%timeit np.where(df['b'].isna())[0]
%timeit df.loc[pd.isna(df['b']), :].index

Và thời gian tương ứng của chúng:

333 µs ± 9.95 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
280 µs ± 220 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
313 µs ± 128 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
6.84 ms ± 1.59 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Có vẻ như pd.isnull(df['DRGWeight']).nonzero()[0]sẽ thắng trong ngày về mặt thời gian, nhưng bất kỳ phương pháp nào trong ba phương pháp hàng đầu đều có hiệu suất tương đương.


3

trong trường hợp bạn có chỉ mục ngày giờ và bạn muốn có các giá trị:

df.loc[pd.isnull(df).any(1), :].index.values

2

Một giải pháp đơn giản khác là list(np.where(df['b'].isnull())[0])


1

Đây là một cách đơn giản hơn:

df = pd.DataFrame([[0,1,3,4,np.nan,2],[3,5,6,np.nan,3,3]])

inds = np.asarray(df.isnull()).nonzero()

(array([0, 1], dtype=int64), array([4, 3], dtype=int64))

1

Tôi đang tìm kiếm tất cả các chỉ mục của các hàng có giá trị NaN.
Giải pháp làm việc của tôi:

def get_nan_indexes(data_frame):
    indexes = []
    print(data_frame)
    for column in data_frame:
        index = data_frame[column].index[data_frame[column].apply(np.isnan)]
        if len(index):
            indexes.append(index[0])
    df_index = data_frame.index.values.tolist()
    return [df_index.index(i) for i in set(indexes)]

0

Đặt tên dataframe là df và cột quan tâm (tức là cột mà chúng ta đang cố gắng tìm giá trị rỗng ) là 'b' . Sau đó, đoạn mã sau cung cấp chỉ số null mong muốn trong khung dữ liệu:

   for i in range(df.shape[0]):
       if df['b'].isnull().iloc[i]:
           print(i)
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.