2017-07-07 5 views
3

Ich habe 12 eindeutige Gruppen, die ich zufällig aus verschiedenen Gruppen mit jeweils einer anderen Anzahl von Beobachtungen probiere. Ich möchte eine zufällige Stichprobe von der gesamten Population (Datenrahmen) machen, wobei jede Gruppe die gleiche Wahrscheinlichkeit hat, ausgewählt zu werden. Das einfachste Beispiel hierfür wäre ein Datenrahmen mit 2 Gruppen.Zufällig aus Pandas-Gruppen mit gleicher Wahrscheinlichkeit auswählen - unerwartetes Verhalten

groups probability 
0  a  0.25 
1  a  0.25 
2  b  0.5 

mit np.random.choice(df['groups'], p=df['probability'], size=100) Jede Iteration wird nun eine Chance von 50% group a Auswahl und eine 50% ige Chance der Auswahl group b

mit den Wahrscheinlichkeiten zu kommen habe ich die Formel:

(1./num_groups)/size_of_groups 

oder in Python:

num_groups = len(df['groups'].unique()) # 2 
size_of_groups = df.groupby('label').size() # {a: 2, b: 1} 
(1./num_groups)/size_of_groups 

Was gibt

zurück
groups 
a 0.25 
b 0.50 

Das funktioniert gut, bis ich vorbei 10 einzigartige Gruppen, nach denen ich seltsame Verteilungen bekommen. Hier ist ein kleines Beispiel:

np.random.seed(1234) 

group_size = 12 
groups = np.arange(group_size) 

probs = np.random.uniform(size=group_size) 
probs = probs/probs.sum() 

g = np.random.choice(groups, size=10000, p=probs) 
df = pd.DataFrame({'groups': g}) 

prob_map = ((1./len(df['groups'].unique()))/df.groupby('groups').size()).to_dict() 

df['probability'] = df['groups'].map(prob_map) 

plt.hist(np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True)) 
plt.xticks(np.arange(group_size)) 
plt.show() 

Histogram

Ich würde eine ziemlich gleichmäßige Verteilung mit einer ausreichend großen Probengröße erwarten würde, aber ich bin immer diese Flügel, wenn die Anzahl der Gruppen 11+ ist. Wenn ich die group_size Variable auf 10 oder niedriger ändere, bekomme ich die gewünschte gleichmäßige Verteilung.

Ich kann nicht sagen, ob das Problem mit meiner Formel für die Berechnung der Wahrscheinlichkeiten oder möglicherweise ein Gleitkomma-Genauigkeitsproblem ist? Wer weiß einen besseren Weg, dies zu erreichen, oder eine Lösung für dieses Beispiel?

Vielen Dank im Voraus!

Antwort

2

Sie verwenden hist die standardmäßig 10 Container ...

enter image description here

plt.rcParams['hist.bins'] 

10 

Pass group_size als bins Parameter.

plt.hist(
    np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True), 
    bins=group_size) 

enter image description here

+0

Ahh, das macht Sinn! Danke für die schnelle Antwort! – pyrate

2

Es gibt kein Problem über Ihre Berechnungen. Ihre resultierende Array ist:

arr = np.random.choice(df['groups'], p=df['probability'], size=10000, replace=True) 

Wenn Sie den Wert zählt überprüfen:

pd.Series(arr).value_counts().sort_index() 
Out: 
0  855 
1  800 
2  856 
3  825 
4  847 
5  835 
6  790 
7  847 
8  834 
9  850 
10 806 
11 855 
dtype: int64 

Es ist ziemlich nah an einer gleichmäßigen Verteilung. Das Problem ist mit der Standardanzahl von Bins (10) des Histogramms.Stattdessen versuchen Sie dies:

bins = np.linspace(-0.5, 10.5, num=12) 
pd.Series(arr).plot.hist(bins=bins) 

enter image description here

+0

Danke für die schnelle Antwort! Ich hätte nachdenken sollen, den Wert zu prüfen! – pyrate

+0

@pyrate Gern geschehen. Im Allgemeinen kann das Histogramm für eine diskrete Menge von Werten irreführend sein, so dass ja value_counts + und ein Balkendiagramm in der Entdeckungsphase nützlicher sein könnte. – ayhan