代码之家  ›  专栏  ›  技术社区  ›  muni

从数据帧中的多个列获取最大频率的项

  •  -3
  • muni  · 技术社区  · 7 年前

    我有一个这样的数据框:

    a1  a2  a3  a4
    4   4   4   4
    4   4   4   4
    2   3   2   3
    2   3   3   3
    2   2   2   2
    2   2   2   2
    

    期望输出:

    a1  a2  a3  a4  max_freq
    4   4   4   4   4
    4   4   4   4   4
    2   3   2   3   3
    2   3   3   3   3
    2   2   2   2   2
    2   2   2   2   2
    

    我想从列返回元素,这在列a1、a2、a3、a4中最水平地出现。例如,4 freq-4,所以max_freq=4,依此类推。如果是领带,请返回a4。

    我一开始就想:

    def get_max_freq(row):
        unique, counts = np.unique(np.array(row), return_counts=True)
        print (unique,counts)
    
    df_temp.apply(get_max_freq, axis=1)
    

    我可以得到每行项目的频率。我可以继续尝试将它们转换为数据帧,按计数排序,选择第一个元素并从函数返回,但这似乎是一个缓慢的方法。有什么方法可以解决这个问题吗?(它可以解决~1m行数据帧上的速度问题)

    2 回复  |  直到 7 年前
        1
  •  3
  •   user3483203    7 年前

    如果你关心速度,而不关心 a4 正如您在评论中提到的,您可以使用 scipy.stats.mode :

    df['freq'] = scipy.stats.mode(df.values, 1)[0]
    
       a1  a2  a3  a4  freq
    0   4   4   4   4     4
    1   4   4   4   4     4
    2   2   3   2   3     2
    3   2   3   3   3     3
    4   2   2   2   2     2
    5   2   2   2   2     2
    

    时间安排

    df = pd.concat([df]*10000)
    
    In [244]: %timeit df.mode(1)
    12.7 s ± 268 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [245]: %timeit scipy.stats.mode(df.values, 1)[0]
    10.8 ms ± 515 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    这会给你一个 大量的 性能提升超过 mode(1)

        2
  •  1
  •   rafaelc    7 年前

    好像你想要 pd.Series.mode

    df['max_freq'] = df.agg(lambda x: x.mode() if x.mode().size==1 else x['a4'], axis=1)
    
        a1  a2  a3  a4  max_freq
    0   4   4   4   4   4
    1   4   4   4   4   4
    2   2   3   2   3   3
    3   2   3   3   3   3
    4   2   2   2   2   2
    5   2   2   2   2   2
    
    推荐文章