【问题标题】:Applying last valid index mask to dataframe to get last valid values将最后一个有效索引掩码应用于数据帧以获取最后一个有效值
【发布时间】:2018-11-24 10:32:03
【问题描述】:

我有一个如下所示的数据框:

    s1        s2       s3       s4
0   v1        v2       v3       v4
0   v5        v6       v7       np.nan
0   v8      np.nan     v9       np.nan
0   v10     np.nan     np.nan   np.nan

基本上从上到下都有数值,并且在某些随机索引值处跨列将仅切换到 np.nan。

我已经使用 .apply(pd.Series.last_valid_index) 来获取值仍然是数字的索引,但是,我不确定检索我拥有实际值的系列的最有效方法最后一个有效索引处的值。

理想情况下,我能够推导出一个看起来像这样的系列:

   value
s1 v10
s2 v6
s3 v9
s4 v4

或作为看起来像的数据框

   s1 s2 s3 s4
0 v10 v6 v9 v4

非常感谢!

【问题讨论】:

    标签: python performance pandas numpy


    【解决方案1】:

    这是使用 NumPy 索引的一种方式:

    # ensure index is normalised
    df = df.reset_index(drop=True)
    
    # calculate last valid index across dataframe
    idx = df.apply(pd.Series.last_valid_index)
    
    # create result using NumPy indexing
    res = pd.Series(df.values[idx, np.arange(df.shape[1])],
                    index=df.columns,
                    name='value')
    
    print(res)
    
    s1    v10
    s2     v6
    s3     v9
    s4     v4
    Name: value, dtype: object
    

    【讨论】:

      【解决方案2】:

      这是另一种方法,无需重置索引:

      df.apply(lambda x: x[x.notnull()].values[-1])
      
      s1    v10
      s2     v6
      s3     v9
      s4     v4
      

      【讨论】:

      • 不错的解决方案 +1,您知道 last_valid_index 是否比通过 pd.Series.notnull 的布尔索引更有效吗?
      • 谢谢,不确定,但应该很容易测试...等一下
      • 基于对大df的超级粗略测试,我认为last_valid_index实际上比notnull()快了不少
      • 感谢测试。是的,我是这么认为的,也许last_valid_index 会像生成器一样倒退,而不是测试每个项目。
      • x[x.notnull()] 可以替换为x.dropna()
      【解决方案3】:

      您需要规范化索引,​​找到每列的最后一个有效索引并从中创建一个数据框。

      df = df.reset_index(drop=True)
      ser = df.apply(lambda x: x.last_valid_index())
      pd.DataFrame([df[col][ser[col]] for col in df.columns], index=df.columns).T
      

      输出:

           s1 s2  s3  s4
      0   v10 v6  v9  v4
      

      此外,这样一来,您原来的df 将保持不变。

      【讨论】:

      • 感谢您的快速回复!我试过这个,但我收到以下错误:TypeError: cannot do label indexing on with these indexers [nan] of
      • 你确定它来自我的代码吗?哪条线?你为 pandas 运行什么版本?
      • 似乎是第二行: Traceback(最近一次调用最后一次):文件“”,第 26 行,在 print(pd.DataFrame( [df.reset_index()[col][ser[col]] for col in df.columns], index=df.columns).T) TypeError: cannot do label indexing on 的这些索引器 [nan]
      • df.reset_index()[col].iloc[ser[col]],这对你有用吗?如果是这样,我会更新我的答案。我正在为熊猫使用“0.23.0”版本。这个对我有用。你用的是哪个版本?
      • 我想通了,我不得不删除所有值都是 np.nan 的列 - 然后它就像一个魅力!非常感谢!
      猜你喜欢
      • 2021-03-21
      • 2021-07-18
      • 2018-12-01
      • 1970-01-01
      • 2014-03-03
      • 2018-10-16
      • 2022-12-20
      • 2014-05-09
      • 1970-01-01
      相关资源
      最近更新 更多