web-dev-qa-db-fra.com

Localisez les première et dernière valeurs non NaN dans un Pandas DataFrame

J'ai un Pandas DataFrame indexé par date. Il y a un certain nombre de colonnes mais beaucoup de colonnes ne sont remplies que pour une partie de la série chronologique. J'aimerais trouver où le premier et les dernières valeurs les valeurs non -NaN sont situées afin que je puisse extraire les dates et voir combien de temps la série chronologique est pour une colonne particulière.

Quelqu'un pourrait-il m'indiquer dans la bonne direction comment je pourrais faire quelque chose comme ça? Merci d'avance.

44
Jason

La solution de @ behzad.nouri a parfaitement fonctionné pour renvoyer le premier et le dernier nonNaN values en utilisant Series.first_valid_index et Series.last_valid_index , respectivement.

40
Jason

Voici quelques exemples utiles.

Séries

s = pd.Series([np.NaN, 1, np.NaN, 3, np.NaN], index=list('abcde'))
s

a    NaN
b    1.0
c    NaN
d    3.0
e    NaN
dtype: float64

# first valid index
s.first_valid_index()
# 'b'

# first valid position
s.index.get_loc(s.first_valid_index())
# 1

# last valid index
s.last_valid_index()
# 'd'

# last valid position
s.index.get_loc(s.last_valid_index())
# 3

Solution alternative utilisant notna et idxmax:

# last valid index
s.notna().idxmax()
# 'b'

# last valid position
s.notna()[::-1].idxmax()
# 'd'

Trame de données

df = pd.DataFrame({
    'A': [np.NaN, 1, np.NaN, 3, np.NaN], 
    'B': [1, np.NaN, np.NaN, np.NaN, np.NaN]
})
df

     A    B
0  NaN  1.0
1  1.0  NaN
2  NaN  NaN
3  3.0  NaN
4  NaN  NaN

(first|last)_valid_index n'est pas défini sur les DataFrames, mais vous pouvez les appliquer sur chaque colonne à l'aide de apply.

# first valid index for each column
df.apply(pd.Series.first_valid_index)

A    1
B    0
dtype: int64

# last valid index for each column
df.apply(pd.Series.last_valid_index)

A    3
B    0
dtype: int64

Comme précédemment, vous pouvez également utiliser notna et idxmax. Il s'agit d'une syntaxe légèrement plus naturelle.

# fast valid index
df.notna().idxmax()

A    1
B    0
dtype: int64

# last valid index
df.notna()[::-1].idxmax()

A    3
B    0
dtype: int64
5
cs95