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

每个特定组的数据帧随机特定行[重复]

  •  -1
  • Cranjis  · 技术社区  · 4 年前

    假设我有一个数据帧,看起来像:

    Name Group_Id
    AAA  1
    ABC  1
    CCC  2
    XYZ  2
    DEF  3 
    YYH  3
    

    我如何为每一行随机选择一行(或多行) Group_Id ?说我想每个随机抽取一个 组Id ,我会得到:

    Name Group_Id
    AAA  1
    XYZ  2
    DEF  3
    
    0 回复  |  直到 12 年前
        1
  •  64
  •   Zero    9 年前

    从…起 0.16.x 向前 pd.DataFrame.sample 提供了一种从对象轴返回项目的随机样本的方法。

    In [664]: df.groupby('Group_Id').apply(lambda x: x.sample(1)).reset_index(drop=True)
    Out[664]:
      Name  Group_Id
    0  ABC         1
    1  XYZ         2
    2  DEF         3
    
        2
  •  49
  •   behzad.nouri    12 年前
    size = 2        # sample size
    replace = True  # with replacement
    fn = lambda obj: obj.loc[np.random.choice(obj.index, size, replace),:]
    df.groupby('Group_Id', as_index=False).apply(fn)
    
        3
  •  18
  •   mikkokotila    8 年前

    有两种方法可以非常简单地做到这一点,其中一种不使用任何东西,只使用基本的panda语法:

    df[['x','y']].groupby('x').agg(pd.DataFrame.sample)
    

    对于50k行数据集,这需要14.4ms。

    另一种稍微快一点的方法涉及numpy。

    df[['x','y']].groupby('x').agg(np.random.choice)
    

    对于(相同的)50k行数据集,这需要10.9ms。

    一般来说,在使用panda时,最好使用其原生语法。尤其是初学者。

        4
  •  16
  •   user3826929    5 年前
        5
  •  11
  •   grasshopper    12 年前

    在优雅的单行中使用groupby和random.choice:

    df.groupby('Group_Id').apply(lambda x :x.iloc[random.choice(range(0,len(x)))])
    
        6
  •  10
  •   ihadanny    4 年前

    对于每组仅随机选择一行,请尝试:

    df.sample(frac = 1.0).groupby('Group_Id').head(1)
    
        7
  •  9
  •   Reveille    6 年前

    如果一组的样本少于所需的样本量,则提供的解决方案将失败 n 。这解决了这个问题:

    n = 10
    df.groupby('Group_Id').apply(lambda x: x.sample(min(n,len(x)))).reset_index(drop=True)
    
        8
  •  2
  •   Selah    6 年前

    一种非常像熊猫的方式:

    takesamp = lambda d: d.sample(n)
    df = df.groupby('Group_Id').apply(takesamp)
    
        9
  •  1
  •   gravetii    12 年前

    使用 random.choice ,你可以这样做:

    import random
    name_group = {'AAA': 1, 'ABC':1, 'CCC':2, 'XYZ':2, 'DEF':3, 'YYH':3}
    
    names = [name for name in name_group.iterkeys()] #create a list out of the keys in the name_group dict
    
    first_name = random.choice(names)
    first_group = name_group[first_name]
    print first_name, first_group
    

    random.choice(seq)

    Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.
    
        10
  •  1
  •   YS-L    12 年前

    您可以使用 pandas.groupby , pandas.concat 和 random.sample :

    import pandas as pd
    import random
    
    df = pd.DataFrame({
            'Name': ['AAA', 'ABC', 'CCC', 'XYZ', 'DEF', 'YYH'],
            'Group_ID': [1,1,2,2,3,3]
         })
    
    grouped = df.groupby('Group_ID')
    df_sampled = pd.concat([d.ix[random.sample(d.index, 1)] for _, d in grouped]).reset_index(drop=True)
    print df_sampled
    

    输出:

       Group_ID Name
    0         1  AAA
    1         2  XYZ
    2         3  DEF
    
        11
  •  0
  •   ansev    5 年前

    我找到了另一个:

    size=2
    count_s = df['Id'].value_counts()
    df.iloc[np.concatenate([previous_count + np.random.choice(count, size) 
                            for count, previous_count in zip(count_s, 
                                                             count_s.shift(fill_value=0))])]
    
        12
  •  0
  •   Mykola Zotko    3 年前

    您可以使用 sample 和 drop_duplicates :

    df.sample(frac = 1.0).drop_duplicates('Group_Id', ignore_index=True)