在不是NaN的列中查找第一个和/或最后一个值的索引

And*_*ver 7 python numpy dataframe pandas

我正在处理钻孔的地下测量,其中每种测量类型都覆盖不同的深度范围。在这种情况下,深度被用作索引。

我需要找到每种测量类型的第一次和/或最后一次出现的数据(非NaN值)的深度(索引)。

获取数据框第一行或最后一行的深度(索引)很容易:df.index[0]df.index[-1]。诀窍在于找到任何给定列的第一个或最后一个非NaN出现的索引。

df = pd.DataFrame([[500, np.NaN, np.NaN,     25],
                   [501, np.NaN, np.NaN,     27],
                   [502, np.NaN,     33,     24],
                   [503,      4,     32,     18],
                   [504,     12,     45,      5],
                   [505,      8,     38, np.NaN]])
df.columns = ['Depth','x1','x2','x3']
df.set_index('Depth')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

理想解决方案对于x1的首次出现将产生503的索引(深度),对于x2的首次出现将产生502(索引),对于x3的最后一次出现将产生504(索引)。

小智 5

可以使用first_valid_index ()和last_valid_index()。

    >>> df
             x1    x2    x3
    Depth
    500     NaN   NaN  25.0
    501     NaN   NaN  27.0
    502     NaN  33.0  24.0
    503     4.0  32.0  18.0
    504    12.0  45.0   5.0
    505     8.0  38.0   NaN
    >>> df["x1"].first_valid_index()
    503
    >>> df["x2"].first_valid_index()
    502
    >>> df["x3"].first_valid_index()
    500
    >>> df["x3"].last_valid_index()
    504
Run Code Online (Sandbox Code Playgroud)


Sco*_*ton 2

如果我理解正确的话,让我们试试这个:

pd.concat([df.apply(pd.Series.first_valid_index),
           df.apply(pd.Series.last_valid_index)], 
           axis=1, 
           keys=['Min_Depth', 'Max_Depth'])
Run Code Online (Sandbox Code Playgroud)

输出:

      Min_Depth   Max_Depth
x1          503         505
x2          502         505
x3          500         504
Run Code Online (Sandbox Code Playgroud)

或转置输出:

pd.concat([df.apply(pd.Series.first_valid_index),
           df.apply(pd.Series.last_valid_index)], 
           axis=1, 
           keys=['Min_Depth', 'Max_Depth']).T
Run Code Online (Sandbox Code Playgroud)

输出:

            x1   x2   x3
Min_Depth  503  502  500
Max_Depth  505  505  504
Run Code Online (Sandbox Code Playgroud)

将 apply 与函数列表一起使用:

df.apply([pd.Series.first_valid_index, pd.Series.last_valid_index])
Run Code Online (Sandbox Code Playgroud)

输出:

                    x1   x2   x3
first_valid_index  503  502  500
last_valid_index   505  505  504
Run Code Online (Sandbox Code Playgroud)

稍微重命名一下:

df.apply([pd.Series.first_valid_index, pd.Series.last_valid_index])\
  .set_axis(['Min_Depth', 'Max_Depth'], axis=0, inplace=False)
Run Code Online (Sandbox Code Playgroud)

输出:

            x1   x2   x3
Min_Depth  503  502  500
Max_Depth  505  505  504
Run Code Online (Sandbox Code Playgroud)