在Pandas DataFrame中找到第一个和最后一个非NaN值

Jas*_*son 47 python datetime pandas

我有一个DataFrame按日期索引的熊猫.有许多列,但许多列仅填充部分时间序列.我想找到非NaN值的第一个和最后一个值的位置,以便我可以提取日期并查看特定列的时间序列有多长.

有人能指出我如何做这样的事情吗?提前致谢.

Jas*_*son 42

@ behzad.nouri的解决方案完美地分别返回第一个和最后一个非NaN values使用Series.first_valid_indexSeries.last_valid_index.

  • 您可以使用“df.apply(Series.first_valid_index)”,而不是迭代 DataFrame 的列。 (2认同)

cs9*_*s95 8

这是一些有用的例子。

系列

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
Run Code Online (Sandbox Code Playgroud)

使用notna和的替代解决方案idxmax

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

# last valid position
s.notna()[::-1].idxmax()
# 'd'
Run Code Online (Sandbox Code Playgroud)

数据框

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
Run Code Online (Sandbox Code Playgroud)

(first|last)_valid_index未在DataFrames上定义,但是您可以使用将它们应用于每列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
Run Code Online (Sandbox Code Playgroud)

和以前一样,您也可以使用notnaidxmax。这是更自然的语法。

# 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
Run Code Online (Sandbox Code Playgroud)

  • “idxmax()”的问题在于,对于完整的“NaN”列,它将返回“0”。在这种情况下,我希望得到一个 `NaN`,所以我宁愿总是使用 `.apply(Series.first_valid_index)`。 (3认同)