【问题标题】:pandas - create dataframe with counts and frequency of elementspandas - 创建具有元素计数和频率的数据框
【发布时间】:2016-03-09 19:49:10
【问题描述】:

从以下数据框df开始:

df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']})

我正在尝试构建结构:

    node     langs   lfreq
0      1      [it]     [1]
1      2      [en]     [1]
2      3  [ar, es]  [2, 1]
3      5  [uz, es]  [1, 1]

所以基本上通过列表将lang 元素和每个节点的频率分组到单行中。到目前为止我做了什么:

# Getting the unique langs / node
a = df.groupby('node')['lang'].unique().reset_index(name='langs')

# Getting the frequency of lang / node
b = df.groupby('node')['lang'].value_counts().reset_index(name='lfreq')
c = b.groupby('node')['lfreq'].unique().reset_index(name='lfreq')

然后在node上合并:

d = pd.merge(a,c,on='node')

经过这些操作,我得到的是:

    node     langs   lfreq
0      1      [it]     [1]
1      2      [en]     [1]
2      3  [ar, es]  [2, 1]
3      5  [uz, es]     [1]

您可能注意到,最后一行只有一个[1] 出现两个[uz, es] 的频率,而不是预期的[1,1] 列表。有没有办法以更简洁的方式执行分析以获得所需的输出?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我会使用 agg 函数和 tolist()

    df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']})
    # Getting the unique langs / node
    a = df.groupby('node')['lang'].unique().reset_index(name='langs')
    
    # Getting the frequency of lang / node
    b = df.groupby('node')['lang'].value_counts().reset_index(name='lfreq')
    

    替换

    c = b.groupby('node')['lfreq'].unique().reset_index(name='lfreq')
    

    c = b.groupby('node').agg({'lfreq': lambda x: x.tolist()}).reset_index()
    
    d = pd.merge(a,c,on='node')
    

    和中提琴:

       node     langs   lfreq
    0     1      [it]     [1]
    1     2      [en]     [1]
    2     3  [ar, es]  [2, 1]
    3     5  [uz, es]  [1, 1]
    

    【讨论】:

      【解决方案2】:

      部分是因为您(在评论中)提到速度对于拥有 4000 万行的重要性,我建议您查看更接近以下内容的内容。

      df.groupby(['node','lang'])['lang'].count()
      
      node  lang
      1     it      1
      2     en      1
      3     ar      2
            es      1
      5     es      1
            uz      1
      

      一般来说,使用更扁平的结构(python 之禅)会更好,更具体地说,您希望 pandas/numpy 列是简单类型(整数和浮点数),而不是对象。

      考虑到像 groupby 这样的 pandas 方法,上述结构应该比存储为列表更容易做事,并且几乎可以保证更快,可能更快。我假设您想使用此结构进行进一步处理,但即使没有,以这种方式将数据制成表格也会更快。

      【讨论】:

      • 实际上在 500.000 行数据帧上,@JohnE 解决方案比 dmb(64 秒)和 jezrael(136 秒)快得多(1.5 秒)。
      【解决方案3】:

      你可以applynp.unique带参数return_counts=True:

      df = pd.DataFrame({'node':[1,2,3,3,3,5,5],'lang':['it','en','ar','ar','es','uz','es']})
      print df
        lang  node
      0   it     1
      1   en     2
      2   ar     3
      3   ar     3
      4   es     3
      5   uz     5
      6   es     5
      
      a = df.groupby('node')['lang'].apply(lambda x: np.unique(x, return_counts=True))
                                    .reset_index(name='tup')
      
      #split tuples
      a[['langs','lfreq']] = a['tup'].apply(pd.Series)
      #filter columns
      print a[['node','langs','lfreq']]
         node     langs   lfreq
      0     1      [it]     [1]
      1     2      [en]     [1]
      2     3  [ar, es]  [2, 1]
      3     5  [es, uz]  [1, 1]
      

      【讨论】:

      • 谢谢。与其他答案相比,速度如何?我知道 apply 对于大型数据帧很慢(我有近 4000 万行)
      猜你喜欢
      • 1970-01-01
      • 2014-03-01
      • 2021-08-19
      • 2016-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多