web-dev-qa-db-fra.com

Rechercher un index entier de lignes avec NaN dans un cadre de données de pandas

J'ai un DataFrame comme ceci:

                    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

Existe-t-il un moyen efficace de rechercher l'index "entier" des lignes contenant des NaN? Dans ce cas, la sortie souhaitée doit être [3, 6].

62
user1642513

Pour DataFrame df:

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

vous redonnera la MultiIndex que vous pouvez utiliser pour indexer dans df, par exemple:

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

Pour l'index entier:

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

Voici une solution plus simple:

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])
126
Wes McKinney

Et juste au cas où, si vous voulez plutôt trouver les coordonnées de 'nan' pour toutes les colonnes (en supposant qu'elles soient toutes numériques), voici ce que vous allez faire:

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]))
6
Filippo Mazza

Je ne sais pas si c'est trop tard, mais vous pouvez utiliser np.where pour trouver les indices de non-valeurs en tant que tels:

indices = np.where(df['b'].isna())
3
naturesenshi

Une solution en ligne. Cependant, cela ne fonctionne que pour une colonne.

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

Voici une autre prise plus simple:

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
nonya beeswax

Laissez le dataframe être nommé df et la colonne d’intérêt (c.-à-d. La colonne dans laquelle nous essayons de trouver des valeurs nuls) est 'b'. Alors l'extrait suivant donne l'index souhaité de null dans le cadre de données:

   for i in range(df.shape[0]):
       if df['b'].isnull().iloc[i]:
           print(i)
0
Stone Austin

Je cherchais tous les index des lignes avec des valeurs de NaN.
Ma solution de travail:

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
murthy10

Voici des tests pour quelques méthodes:

%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

Et leurs timings correspondants:

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)

Il semblerait que pd.isnull(df['DRGWeight']).nonzero()[0] gagne la journée en termes de timing, mais que l’une des trois méthodes les plus performantes présente des performances comparables.

0
Adam Erickson

dans le cas où vous avez un index datetime et que vous voulez avoir les valeurs:

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