Am urmatoarele DataFrame:
Col1 Col2 Col3 Type
0 1 2 3 1
1 4 5 6 1
...
20 7 8 9 2
21 10 11 12 2
...
45 13 14 15 3
46 16 17 18 3
...
DataFrame este citit dintr-un fișier csv. Toate rândurile care au " Tip "1 sunt pe partea de sus, urmat de rânduri cu" Tip "2, urmat de rânduri cu" Tip " 3, etc.
Aș dori pentru a amesteca ordinea de DataFrame's randuri, astfel încât toate " Tip " 's sunt amestecate. Un rezultat posibil ar putea fi:
Col1 Col2 Col3 Type
0 7 8 9 2
1 13 14 15 3
...
20 1 2 3 1
21 10 11 12 2
...
45 4 5 6 1
46 16 17 18 3
...
Cum pot realiza acest lucru?
Idiomatic mod de a face acest lucru cu panda este de a utiliza .proba
metoda de dataframe, adică
python df.eșantion(frac=1)
Anii frac
cuvinte cheie argument specifică fracțiune de rânduri pentru a reveni în eșantion aleatoriu, deci frac=1
înseamnă a reveni toate rândurile (în ordine aleatorie).
Notă:
Dacă doriți să shuffle dataframe în loc și a reseta index, ai putea face de exemplu
python df = df.eșantion(frac=1).reset_index(drop=True)
Aici, specificând drop=True
impiedica `.reset_index de a crea o coloană care conține index vechi înregistrări.
Follow-up notă: Deși nu poate arata ca operațiunea de mai sus este în loc de, python/panda este suficient de inteligent să nu facă un alt malloc pentru amestecat obiect. Asta este, chiar dacă referință obiect s-a schimbat (adică id(df_old)
nu este același lucru ca id(df_new)
), care stau la baza C obiect este în continuare același. Pentru a arăta că acest lucru este într-adevăr cazul, ai putea rula un joc simplu de memorie profiler:
``
$ python3 -m memory_profiler .\test.py
Filename: .\test.py
5 68.5 MiB 68.5 MiB @profil 6 def shuffle(): 7 847.8 MiB 779.3 MiB df = pd.DataFrame(np.aleatoare.randn(100, 1000000)) 8 847.9 MiB 0.1 MiB df = df.eșantion(frac=1).reset_index(drop=True)
``
Puteți amesteca rânduri de un dataframe prin indexarea cu o amestecate index. Pentru aceasta, puteți de exemplu folosesc np.aleatoare.permutare` (dar np.aleatoare.alegerea este, de asemenea, o posibilitate):
In [12]: df = pd.read_csv(StringIO(s), sep="\s+")
In [13]: df
Out[13]:
Col1 Col2 Col3 Type
0 1 2 3 1
1 4 5 6 1
20 7 8 9 2
21 10 11 12 2
45 13 14 15 3
46 16 17 18 3
In [14]: df.iloc[np.random.permutation(len(df))]
Out[14]:
Col1 Col2 Col3 Type
46 16 17 18 3
45 13 14 15 3
20 7 8 9 2
0 1 2 3 1
1 4 5 6 1
21 10 11 12 2
Dacă doriți să păstrați indicele numerotate de la 1, 2, .., n, ca în exemplu, puteți reseta pur și simplu index: df_shuffled.reset_index(drop=True)
TL;DR: np.aleatoare.shuffle(ndarray)
poate face treaba.
Deci, în cazul tău
np.random.shuffle(DataFrame.values)
DataFrame
, sub capota, foloseste NumPy ndarray ca deținătorul de date. (Puteți verifica de la DataFrame codul sursă)
Deci, dacă utilizați np.random.shuffle()
ar amesteca matrice de-a lungul primei axe de un multi-dimensional matrice. Dar indicele de DataFrame rămâne unshuffled.
Totuși, există câteva puncte să ia în considerare.
sklearn.utils.shuffle()
ca utilizator tj89 sugerat, poate desemna `random_state împreună cu o altă opțiune pentru a controla de ieșire. Poate doriți pentru dev scop.sklearn.utils.shuffle()
este mai rapid. Dar VA AMESTECA axa info(indicele de coloană) a DataFrame
împreună cu ndarray
le conține.între sklearn.utils.shuffle()
și np.random.shuffle()
.
nd = sklearn.utils.shuffle(nd)
0.10793248389381915 sec. 8x mai rapid
np.random.shuffle(nd)
0.8897626010002568 sec
df = sklearn.utils.shuffle(df)
0.3183923360193148 sec. 3x mai rapid
np.random.shuffle(df.values)
0.9357550159329548 sec
Concluzie: Dacă este bine să axa info(index, coloana) pentru a fi amestecate împreună cu ndarray, utilizare
sklearn.utils.shuffle()
. În caz contrar, utilizaținp.random.shuffle()
import timeit
setup = '''
import numpy as np
import pandas as pd
import sklearn
nd = np.random.random((1000, 100))
df = pd.DataFrame(nd)
'''
timeit.timeit('nd = sklearn.utils.shuffle(nd)', setup=setup, number=1000)
timeit.timeit('np.random.shuffle(nd)', setup=setup, number=1000)
timeit.timeit('df = sklearn.utils.shuffle(df)', setup=setup, number=1000)
timeit.timeit('np.random.shuffle(df.values)', setup=setup, number=1000)
[tag:python][tag:benchmarking]
(Nu't au suficient de reputația sa comenteze acest lucru pe postul de sus, asa ca sper ca cineva poate face asta pentru mine.) Nu a fost un motiv de îngrijorare faptul că prima metodă:
df.sample(frac=1)
a făcut o copie profundă sau schimbat doar dataframe. Am fugit următorul cod:
print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))
și rezultatele mele au fost:
0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70
ceea ce înseamnă că metoda este nu revenind la același obiect, așa cum a fost sugerat în ultimul comentariu. Deci, această metodă are într-adevăr face o amestecate copia.
Ce este, de asemenea, util, dacă îl folosiți pentru Machine_learning și doriți pentru a separa întotdeauna aceleași date, ai putea folosi:
df.eșantion(n=len(df), random_state=42)
acest lucru face sigur, că vă păstrați alegere aleatorie întotdeauna replicatable
shuffle panda cadru de date de a lua o mostră de matrice în acest caz index și aleator de ordine, apoi setați matrice ca un indice de cadru de date. Acum sorta datele cadru potrivit index. Aici merge amestecate dataframe
import random
df = pd.DataFrame({"a":[1,2,3,4],"b":[5,6,7,8]})
index = [i for i in range(df.shape[0])]
random.shuffle(index)
df.set_index([index]).sort_index()
ieșire
a b
0 2 6
1 1 5
2 3 7
3 4 8
Introduce cadru de date în loc de-al meu din codul de mai sus .