【问题标题】:Computing the first non-missing value from each column in a DataFrame [duplicate]从DataFrame中的每一列计算第一个非缺失值[重复]
【发布时间】:2014-06-12 03:15:29
【问题描述】:

我有一个如下所示的 DataFrame:

            1125400  5430095  1095751
2013-05-22   105.24      NaN  6507.58
2013-05-23   104.63      NaN  6393.86
2013-05-26   104.62      NaN  6521.54
2013-05-27   104.62      NaN  6609.31
2013-05-28   104.54    87.79  6640.24
2013-05-29   103.91    86.88  6577.39
2013-05-30   103.43    87.66  6516.55
2013-06-02   103.56    87.55  6559.43

我想计算每列中的第一个非 NaN 值。

正如Locate first and last non NaN values in a Pandas DataFrame 指出的那样,可以使用first_valid_index。不幸的是,它返回第一行,其中至少一个元素不是 NaN 并且不能按列工作。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    内置函数DataFrame.groupby().column.first()返回列中第一个非空值,而last()返回最后一个。

    http://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.groupby.GroupBy.first.html

    如果您不希望获得每个组的第一个值,您可以添加一个 1 的虚拟列。然后使用 groupby & first 函数获取第一个非空值。

    from Pandas import DataFrame
    
    df = DataFrame({'a':[None,1,None],'b':[None,2,None]})
    df['dummy'] = 1
    df.groupby('dummy').first()
    df.groupby('dummy').last()
    

    【讨论】:

    • 这仅适用于数字类型。如果任何列是对象类型,那么您将得到 None
    【解决方案2】:

    您应该使用apply 函数,该函数有效地将函数应用于每一列(默认)或每一行:

    >>> first_valid_indices = df.apply(lambda series: series.first_valid_index())
    >>> first_valid_indices
    1125400   2013-05-22 00:00:00
    5430095   2013-05-28 00:00:00
    1095751   2013-05-22 00:00:00
    

    first_valid_indices 将是一个系列,其中包含每列的 first_valid_index。

    您还可以将lambda 函数定义为外部的普通函数:

    def first_valid_index(series):
        return series.first_valid_index()
    

    然后像这样调用apply:

    df.apply(first_valid_index)
    

    【讨论】:

    • 而不是构建一个 lambda 函数,或者一个真正的函数。您可以在 Series 类上使用 unbound 函数。 df.apply(pd.Series.first_valid_index)
    • 上面的代码只给出了它是第一个非空的每一列的索引。它是不完整的,因为它没有提供有关如何在 go 中使用实例的信息。
    【解决方案3】:

    通过计算我假设您的意思是访问?

    最简单的方法是使用pd.Series.first_valid_index() 方法,可能在字典理解中:

    values = {col : DF.loc[DF[col].first_valid_index(), col] for col in DF.columns}
    values
    

    为了清楚起见,pandas DataFrame 中的每一列都是一个系列。所以上面和做的一样:

    values = {}
    for column in DF.columns:
        First_Non_Null_Index = DF[column].first_valid_index()
        values[column] = DF.loc[First_Non_Null_Index, column]
    

    所以我的单行解决方案中的操作是基于每列的。 IE。它不会产生您在对问题所做的编辑中似乎建议的错误类型。让我知道它是否按预期工作。

    【讨论】:

    • 这会起作用,但我希望有一个更简单的方法。如果我使用df.dropna(),它会删除所有包含至少一个 NaN 的行。我可以在每一列上按系列进行,但我希望有一种更简单的方法。
    • 哈哈哈,你不喜欢这个答案。好的。看看更新的答案!!!
    • 在我的解决方案中,它确实适用于每列。每列都是一个熊猫系列,所以 first_valid_index 正在做你想要的......它正在查看数据框的每一列并找到第一个非空索引点并为您提供该点的值。我相信您对问题的编辑是不正确的...
    • 是的,您的解决方案每列都有效,每次都在不同的系列上。 first_valid_index 以我期望的方式适用于系列。在 DataFrame 上调用 first_valid_index 就像我在编辑中描述的那样工作。
    • 所以实际上它完全符合您的要求?
    猜你喜欢
    • 2014-11-21
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多