Python: sélection aléatoire par groupe
Dire que j'ai un dataframe qui ressemble à:
Name Group_Id
AAA 1
ABC 1
CCC 2
XYZ 2
DEF 3
YYH 3
Comment puis-je choisir au hasard une (ou plusieurs) rangée pour chaque Group_Id
? Dites que je veux un tirage au sort par Group_Id
, j'obtiens:
Name Group_Id
AAA 1
XYZ 2
DEF 3
7 réponses
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)
0.16.x
à partir de pd.DataFrame.sample
fournit un moyen de retourner un échantillon aléatoire d'articles à partir d'un axe d'objet.
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
utilisant groupby et random.choix dans un élégant une ligne:
df.groupby('Group_Id').apply(lambda x :x.iloc[random.choice(range(0,len(x)))])
il y a deux façons de faire cela très simplement, une sans utiliser quoi que ce soit sauf la syntaxe de base des pandas:
df[['x','y']].groupby('x').agg(pd.DataFrame.sample)
cela prend 14.4 ms avec un ensemble de données de 50k rangées.
l'autre méthode, légèrement plus rapide, implique num PY.
df[['x','y']].groupby('x').agg(np.random.choice)
cela prend 10.9 ms avec (le même) ensemble de données de ligne de 50k.
en général, lorsqu'on utilise pandas, il est préférable de s'en tenir à sa syntaxe native. Surtout pour les débutants.
pour sélectionner au hasard juste une ligne par groupe essayer df.sample(frac = 1.0).groupby('Group_Id').head(1)
en utilisant random.choice
, vous pouvez faire quelque chose comme ceci:
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.
Vous pouvez utiliser une combinaison de pandas.groupby
,pandas.concat
et 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
Sortie:
Group_ID Name
0 1 AAA
1 2 XYZ
2 3 DEF