【问题标题】:Using .iterrows() with series.nlargest() to get the highest number in a row in a Dataframe使用 .iterrows() 和 series.nlargest() 来获取数据帧中一行中的最高数字
【发布时间】:2018-08-02 05:14:08
【问题描述】:

我正在尝试创建一个使用df.iterrows()Series.nlargest 的函数。我想遍历每一行并找到最大的数字,然后将其标记为1。这是数据框:

A   B    C
9   6    5
3   7    2

这是我想要的输出:

A    B   C
1    0   0
0    1   0

这是我希望在这里使用的功能:

def get_top_n(df, top_n):
    """


    Parameters
    ----------
    df : DataFrame

    top_n : int
        The top number to get
    Returns
    -------
    top_numbers : DataFrame
    Returns the top number marked with a 1

    """
    # Implement Function
    for row in df.iterrows():
        top_numbers = row.nlargest(top_n).sum()

    return top_numbers

我收到以下错误: AttributeError: 'tuple' 对象没有属性 'nlargest'

对于如何以更简洁的方式重新编写我的函数并实际工作的帮助,我们将不胜感激!提前致谢

【问题讨论】:

    标签: python pandas dataframe iterator


    【解决方案1】:

    添加i 变量,因为iterrows 为每一行返回带有Series 的索引:

    for i, row in df.iterrows():
        top_numbers = row.nlargest(top_n).sum()
    

    numpy.argsortdescending order 中的位置进行通用解决方案,然后比较布尔数组并将其转换为整数:

    def get_top_n(df, top_n):
        if top_n > len(df.columns):
            raise ValueError("Value is higher as number of columns")
        elif not isinstance(top_n, int):
            raise ValueError("Value is not integer")
    
        else:
            arr = ((-df.values).argsort(axis=1) < top_n).astype(int)
            df1 = pd.DataFrame(arr, index=df.index, columns=df.columns)
            return (df1)
    
    df1 = get_top_n(df, 2)
    print (df1)
       A  B  C
    0  1  1  0
    1  1  1  0
    
    df1 = get_top_n(df, 1)
    print (df1)
       A  B  C
    0  1  0  0
    1  0  1  0
    

    编辑:

    iterrows 的解决方案是可能的,但不推荐,因为速度慢:

    top_n = 2
    for i, row in df.iterrows():
        top = row.nlargest(top_n).index
        df.loc[i] = 0
        df.loc[i, top] = 1
    
    print (df)
       A  B  C
    0  1  1  0
    1  1  1  0
    

    【讨论】:

    • 好的。那么我还需要实现 iterrows() 吗?最终输出必须放在 top_numbers 变量中。该函数应该返回 top_numbers @jezrael
    • 当我在函数中尝试上面的代码时,我将 df1 更改为 top_numbers。但我现在得到这个错误AssertionError: Wrong value for get_top_n.@jezrael
    • @DeepakM - 好的,那么预期的输出是什么? iterrows 最好避免,因为速度慢。
    • 基本上,我希望函数传入 n_tops 变量中的任意数字。使函数可以重用。因此,当我返回 top_numbers 时,它接受任何数字并且该函数可重用@jezrael
    • 你能在函数本身中定制解决方案吗@jezrael
    【解决方案2】:

    就上下文而言,数据框包含标准普尔 500 指数大约 4 年的股票回报数据

    def get_top_n(prev_returns, top_n):
    
        # generate dataframe populated with zeros for merging
        top_stocks = pd.DataFrame(0, columns = prev_returns.columns, index = prev_returns.index)
    
        # find top_n largest entries by row
        df = prev_returns.apply(lambda x: x.nlargest(top_n), axis=1)
    
        # merge dataframes
        top_stocks = top_stocks.merge(df, how = 'right').set_index(df.index)
    
        # return dataframe replacing non_zero answers with a 1
        return (top_stocks.notnull()) * 1
    

    【讨论】:

      【解决方案3】:

      或者,两行解决方案可以是


      def get_top_n(df, top_n):
      
          # find top_n largest entries by stock
          df = df.apply(lambda x: x.nlargest(top_n), axis=1)
      
          # convert dataframe NaN or float entries True and False, and then convert to 0 and 1
          top_numbers = (df.notnull()).astype(np.int)
      
          return top_numbers
      

      【讨论】:

        猜你喜欢
        • 2021-05-09
        • 2020-12-11
        • 1970-01-01
        • 1970-01-01
        • 2021-08-05
        • 1970-01-01
        • 2018-05-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多