【问题标题】:Create share variable after combined groupby in pandas dataframe在 pandas 数据框中组合 groupby 后创建共享变量
【发布时间】:2019-03-20 02:37:27
【问题描述】:

我无法描述我的问题,所以我将直接进入它。以下是一些测试数据:

import pandas as pd
df = pd.DataFrame(data={"family":["Smith","Miller","Simpson","Miller","Simpson","Smith","Miller","Simpson","Miller"],
                    "first_name":["Anna","Bart","Lisa","Ida","Paul","Bridget","Harry","Dustin","George"],
                    "shirt_color":["green","yellow","red","yellow","green","red","yellow","red","red"]})

现在我想在我的原始数据框中创建一个新列,其中包含每个家庭的 shirt_color 份额,因此每一行都带有例如family Miller 和 shirt_color yellow 具有相同的值 0.75 等。

我尝试了几种方法,但都没有成功。

df = df.groupby("family").apply(lambda x: x.groupby("shirt_color").apply(lambda x: x.size()/familysize))

这看起来很有希望,但正如您所见,我无法再访问最后一个 lambda 函数中的家庭成员数量。我还尝试创建一个只有 family 的 groupby 对象并遍历数据帧,将所有数据帧按颜色单独分组,但不知何故我最终无法将数据帧放回一个。

这对数据框来说似乎不是一件很奇特的事情,所以我确信有一种简单的方法可以做到这一点,但我没有想法。

非常感谢您提前提供的帮助!

【问题讨论】:

    标签: python python-3.x pandas dataframe pandas-groupby


    【解决方案1】:

    你快到了。只需使用不同的变量名。通过同时使用x,您可以覆盖以前的变量,并且无法访问它

    df.groupby("family").apply(lambda s: s.groupby("shirt_color").apply(lambda x: x.size/s.size))
    
    family   shirt_color
    Miller   red            0.250000
             yellow         0.750000
    Simpson  green          0.333333
             red            0.666667
    Smith    green          0.500000
             red            0.500000
    dtype: float64
    

    【讨论】:

      【解决方案2】:

      在我看来,您应该避免使用apply,因为这会导致 Python 级别的循环效率低下。这是使用GroupBy + transform 的替代解决方案:

      f = df.groupby('family')['first_name'].transform('size')
      g = df.groupby(['family', 'shirt_color'])['first_name'].transform('size')
      
      df['ratio'] = g / f
      
      print(df)
      
          family first_name shirt_color     ratio
      0    Smith       Anna       green  0.500000
      1   Miller       Bart      yellow  0.750000
      2  Simpson       Lisa         red  0.666667
      3   Miller        Ida      yellow  0.750000
      4  Simpson       Paul       green  0.333333
      5    Smith    Bridget         red  0.500000
      6   Miller      Harry      yellow  0.750000
      7  Simpson     Dustin         red  0.666667
      8   Miller     George         red  0.250000
      

      【讨论】:

        【解决方案3】:

        试试:

        df.groupby('family').apply(lambda g: g.groupby("shirt_color").apply(lambda x: x.size/g.size)).reset_index()
        

        【讨论】:

          【解决方案4】:

          使用value_countsmerge

          s = (df.groupby('family').shirt_color
                  .value_counts(normalize=True).rename('ratio').reset_index())
          

              family shirt_color     ratio
          0   Miller      yellow  0.750000
          1   Miller         red  0.250000
          2  Simpson         red  0.666667
          3  Simpson       green  0.333333
          4    Smith       green  0.500000
          5    Smith         red  0.500000
          

          将其放回初始 DataFrame 中:

          df.merge(s)
          

              family first_name shirt_color     ratio
          0    Smith       Anna       green  0.500000
          1   Miller       Bart      yellow  0.750000
          2   Miller        Ida      yellow  0.750000
          3   Miller      Harry      yellow  0.750000
          4  Simpson       Lisa         red  0.666667
          5  Simpson     Dustin         red  0.666667
          6  Simpson       Paul       green  0.333333
          7    Smith    Bridget         red  0.500000
          8   Miller     George         red  0.250000
          

          【讨论】:

          • 从来不知道normalize=True! +1
          猜你喜欢
          • 1970-01-01
          • 2011-06-19
          • 2021-01-22
          • 2018-06-10
          • 1970-01-01
          • 2021-09-23
          • 1970-01-01
          • 1970-01-01
          • 2014-07-24
          相关资源
          最近更新 更多