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

时间:2019-07-31 14:47:18

标签: python pandas numpy dataframe

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

我需要找到每种测量类型第一次和/或最后一次出现的数据(非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')

enter image description here

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

4 个答案:

答案 0 :(得分:4)

您可以Test API documentation

df.notna().agg({'x1':'idxmax','x2':'idxmax','x3':lambda x: x[::-1].idxmax()})
#df.notna().agg({'x1':'idxmax','x2':'idxmax','x3':lambda x: x[x].last_valid_index()})

x1    503
x2    502
x3    504

另一种方法是检查第一行是否为nan,并根据该条件应用条件:

np.where(df.iloc[0].isna(),df.notna().idxmax(),df.notna()[::-1].idxmax())

[503, 502, 504]

答案 1 :(得分:4)

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

答案 2 :(得分:2)

IIUC

df.stack().groupby(level=1).head(1)
Out[619]: 
Depth    
500    x3    25.0
502    x2    33.0
503    x1     4.0
dtype: float64

答案 3 :(得分:2)

如果我对您的理解正确,请尝试一下:

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

输出:

      Min_Depth   Max_Depth
x1          503         505
x2          502         505
x3          500         504

或移调输出:

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

输出:

            x1   x2   x3
Min_Depth  503  502  500
Max_Depth  505  505  504

使用带功能列表的应用:

df.apply([pd.Series.first_valid_index, pd.Series.last_valid_index])

输出:

                    x1   x2   x3
first_valid_index  503  502  500
last_valid_index   505  505  504

稍微重命名:

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

输出:

            x1   x2   x3
Min_Depth  503  502  500
Max_Depth  505  505  504