【问题标题】:How to merge pandas value_counts() to dataframe or use it to subset a dataframe如何将 pandas value_counts() 合并到数据帧或使用它来子集数据帧
【发布时间】:2016-06-18 23:00:08
【问题描述】:

我使用 pandas df.value_counts() 来查找特定品牌的出现次数。我想将这些价值计数与初始数据框中的各个品牌合并。

 df has many columns including one named 'brands'
 brands = df.brands.value_counts()

 brand1   143
 brand2   21
 brand3   101
 etc.

如何将值计数与原始数据框合并,以便每个品牌的对应计数位于新列中,例如“brand_count”?

是否可以为这些列分配标题; names 函数不适用于系列,我无法将其转换为数据框以可能以这种方式合并数据。但是,value_counts 输出一系列 dtype int64(品牌名称应该是字符串类型),这意味着我不能执行以下操作:

 df2 = pd.DataFrame({'brands': list(brands_all[0]), "brand_count":
 list(brands_all[1])})
 (merge with df)

最终,我想得到这个:

 col1  col2  col3  brands  brand_count ... col150
                   A        30
                   C        140
                   A        30
                   B        111 

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你想使用transform。

    import numpy as np
    import pandas as pd
    
    np.random.seed(0)
    
    # Create dummy data.
    df = pd.DataFrame({'brands': ['brand{0}'.format(n) 
                       for n in np.random.random_integers(0, 5, 10)]})
    
    df['brand_count'] = \
        df.groupby('brands', as_index=False)['brands'].transform(lambda s: s.count())
    
    >>> df
       brands brand_count
    0  brand4           1
    1  brand5           2
    2  brand0           1
    3  brand3           4
    4  brand3           4
    5  brand3           4
    6  brand1           1
    7  brand3           4
    8  brand5           2
    9  brand2           1
    

    供参考:

    >>> df.brands.value_counts()
    brand3    4
    brand5    2
    brand4    1
    brand0    1
    brand1    1
    brand2    1
    Name: brands, dtype: int64
    

    【讨论】:

    • 这为您提供了包含品牌及其计数的列brand_count,但我想将brand_count 列添加到包含许多其他列的df 中。当我尝试这个时,我会丢失剩余的列
    • 源和目标是同一个数据框吗?如果是这样,df['brand_count'] = ... 将起作用。
    【解决方案2】:

    这就是你想要的:

    import numpy as np
    import pandas as pd
    
    # generating random DataFrame
    brands_list = ['brand{}'.format(i) for i in range(10)]
    a = pd.DataFrame({'brands': np.random.choice(brands_list, 100)})
    b = pd.DataFrame(np.random.randint(0,10,size=(100, 3)), columns=list('ABC'))
    df = pd.concat([a, b], axis=1)
    print(df.head())
    
    # generate 'brands' DF
    brands = pd.DataFrame(df.brands.value_counts().reset_index())
    brands.columns = ['brands', 'count']
    print(brands)
    
    # merge 'df' & 'brands_count'
    merged = pd.merge(df, brands, on='brands')
    print(merged)
    

    PS 第一个重要部分只是生成数据帧。

    你感兴趣的部分从# generate 'brands'DF评论开始

    【讨论】:

      【解决方案3】:
      df = ...
      key_col = "brand"
      count_col = "brand_count"
      
      result = (
          df.join(
              df[key_col].value_counts().rename(count_col), 
              how="left", 
              on=key_col)
      )
      

      如果您需要将计数加入不同的数据帧,请记住用零填充 NaNs:

      df = ...
      other = ...
      key_col = "brand"
      count_col = "brand_count"
      
      result = (
          other.join(
              df[key_col].value_counts().rename(count_col), 
              how="left", 
              on=key_col)
          .fillna({count_col: 0})
      )
      

      【讨论】:

        【解决方案4】:

        Pandas DataFrame 的 merge 和 value_counts 属性非常快,所以我会将两者结合起来。

        df.merge(df['brand'].value_counts().to_frame(), how='left', left_on='brand',
                 right_index=True, suffixes=('', 'x'))\
          .rename(columns={'brandx':'brand_count'})
        

        【讨论】:

          【解决方案5】:

          我认为最好的方法是使用地图

          df['brand_count']= df.brand.map(df.brand.value_counts())
          

          例如,这比 groupby 方法快得多(在 15000 行 df 上因子 500)并且只占用一行

          【讨论】:

          • 超优雅高效的解决方案!它还告诉我 map() 也可以与系列一起使用!谢谢:)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-18
          • 1970-01-01
          • 2015-10-11
          • 2018-08-06
          • 2018-03-03
          • 1970-01-01
          相关资源
          最近更新 更多