2016-07-15 9 views
3

Ich arbeite mit Python-Pandas-Datenrahmen, und ich habe einen großen Datenrahmen, der Benutzer und ihre Daten enthält. Jeder Benutzer kann mehrere Zeilen haben. Ich möchte 1-row pro Benutzer probieren. Meine aktuelle Lösung scheint nicht effizient:Abtastung eines Datensatzes pro eindeutigen Wert (Pandas, Python)

df1 = pd.DataFrame({'User': ['user1', 'user1', 'user2', 'user3', 'user2', 'user3'], 
       'B': ['B', 'B1', 'B2', 'B3','B4','B5'], 
       'C': ['C', 'C1', 'C2', 'C3','C4','C5'], 
       'D': ['D', 'D1', 'D2', 'D3','D4','D5'], 
       'E': ['E', 'E1', 'E2', 'E3','E4','E5']}, 
       index=[0, 1, 2, 3,4,5]) 

df1 
>> B C D E User 
0 B C D E user1 
1 B1 C1 D1 E1 user1 
2 B2 C2 D2 E2 user2 
3 B3 C3 D3 E3 user3 
4 B4 C4 D4 E4 user2 
5 B5 C5 D5 E5 user3 

userList = list(df1.User.unique()) 
userList 
> ['user1', 'user2', 'user3'] 

Die I Schleife über eindeutige Benutzer-Liste und eine Probe Zeile pro Benutzer, so dass sie zu einem anderen Datenrahmen Speicher

usersSample = pd.DataFrame() # empty dataframe, to save samples 
for i in userList: 
    usersSample=usersSample.append(df1[df1.User == i].sample(1)) 

> usersSample 
B C D E User 
0 B C D E user1 
4 B4 C4 D4 E4 user2 
3 B3 C3 D3 E3 user3 

Gibt es eine effizientere Art und Weise zu erreichen, Das? Ich würde wirklich gerne: 1) vermeiden, an Datenframe usersSample anzuhängen. Dies wird allmählich Objekt und es tötet ernsthaft die Leistung. Und 2) vermeiden Sie die Schleife nacheinander über Benutzer. Gibt es eine Möglichkeit, 1-pro-Benutzer effizienter zu testen?

Antwort

8

Dies ist, was Sie wollen:

df1.groupby('User').apply(lambda df: df.sample(1)) 

enter image description here

Ohne den zusätzlichen Index:

df1.groupby('User', group_keys=False).apply(lambda df: df.sample(1)) 

enter image description here

+0

Excellent! Danke, das ist genau das, was ich brauchte! :) – Ruslan

0
df1_user_sample_one = df1.groupby('User').apply(lambda x:x.sample(1)) 

Daten mit Hilfe von Frame.groupby.apply und Lambda-Funktion zur Probe 1

3

Basierend auf der Anzahl der Zeilen pro Benutzer dies schneller sein könnte:

df.sample(frac=1).drop_duplicates(['User']) 
+0

Dies ist schneller auf 'df1'. Langsamer auf 'pd.concat ([df für _ im Bereich (100000)])' – piRSquared

+0

@piRSquared Ich versuchte es auf einem größeren Dataset, aber Typ der Benutzerspalte war Integer (117ms vs 3.96s), aber es scheint, wenn der Typ es ist ist immer langsamer. – ayhan

+0

@piRSquared Ah, der Unterschied kommt von der Anzahl der Benutzer. Die Anzahl der Benutzer ist in diesem Beispiel ziemlich klein. – ayhan

Verwandte Themen