Python:每组随机选择

时间:2014-03-18 06:50:40

标签: python random pandas

假设我有一个类似于:

的数据框
Name Group_Id
AAA  1
ABC  1
CCC  2
XYZ  2
DEF  3 
YYH  3

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

Name Group_Id
AAA  1
XYZ  2
DEF  3

11 个答案:

答案 0 :(得分:18)

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)

答案 1 :(得分:16)

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 :(得分:10)

在优雅的衬里中使用groupby和random.choice:

df.groupby('Group_Id').apply(lambda x :x.iloc[random.choice(range(0,len(x)))])

答案 3 :(得分:5)

有两种方法可以非常简单地执行此操作,除了基本的pandas语法之外没有使用任何其他方法:

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

这需要14.4毫秒,50k行数据集。

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

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

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

一般来说,使用pandas时,最好坚持使用其原生语法。特别适合初学者。

答案 4 :(得分:2)

每组随机选择一行,请尝试df.sample(frac = 1.0).groupby('Group_Id').head(1)

答案 5 :(得分:1)

使用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.

答案 6 :(得分:1)

您可以结合使用pandas.groupbypandas.concatrandom.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

答案 7 :(得分:1)

一种非常像熊猫的方式:

takesamp = lambda d: d.sample(n)
df = df.groupby('Group_Id').apply(takesamp)

答案 8 :(得分:1)

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

n = 10
df.groupby('Group_Id').apply(lambda x: x.sample(min(n,len(x)))).reset_index(drop=True)

答案 9 :(得分:0)

我找到了另一个:

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))])]

答案 10 :(得分:0)