Mam następujące 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 jest odczytywany z pliku csv. Wszystkie wiersze, które mają Type
1, są na górze, następnie wiersze z Type
2, a następnie wiersze z Type
3 itd.
Chciałbym przetasować kolejność wierszy DataFrame, aby wszystkie Type
były pomieszane. Możliwym wynikiem może być:
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
...
Jak mogę to osiągnąć?
.copy()
, nadal odwołujesz się do tego samego obiektu podstawowego.Możesz po prostu użyć do tego sklearn
źródło
Możesz przetasować wiersze ramki danych, indeksując indeksem przetasowanym. W tym celu możesz np. Użyć
np.random.permutation
(alenp.random.choice
jest również możliwość):Jeśli chcesz zachować indeks numerowany od 1, 2, .., n jak w twoim przykładzie, możesz po prostu zresetować indeks:
df_shuffled.reset_index(drop=True)
źródło
TL; DR :
np.random.shuffle(ndarray)
może wykonać zadanie.Więc w twoim przypadku
DataFrame
, pod maską, używa NumPy ndarray jako uchwytu danych. (Możesz sprawdzić z kodu źródłowego DataFrame )Więc jeśli użyjesz
np.random.shuffle()
, przetasuje tablicę wzdłuż pierwszej osi tablicy wielowymiarowej. Ale indeksDataFrame
pozostaje niezmieniony.Chociaż należy wziąć pod uwagę kilka kwestii.
sklearn.utils.shuffle()
, jak sugerował użytkownik tj89, może wyznaczyćrandom_state
wraz z inną opcją sterowania wyjściem. Możesz tego chcieć dla celów programistycznych.sklearn.utils.shuffle()
jest szybszy. Ale BĘDĘ SHUFFLE informacje o osi (indeks, kolumna)DataFrame
wraz zndarray
zawartością.Wynik testu
pomiędzy
sklearn.utils.shuffle()
inp.random.shuffle()
.ndarray
0.10793248389381915 sec. 8x szybciej
0,8897626010002568 sec
Ramka danych
0.3183923360193148 sec. 3x szybciej
0,9357550159329548 sek
użyty kod
pytonanaliza porównawcza
źródło
df = df.sample(frac=1)
robi dokładnie tego samego, codf = sklearn.utils.shuffle(df)
? Według moich pomiarówdf = df.sample(frac=1)
jest szybszy i wydaje się wykonywać dokładnie taką samą akcję. Obaj przydzielają także nową pamięć.np.random.shuffle(df.values)
jest najwolniejszy, ale nie przydziela nowej pamięci.df.sample(frac=1)
jest o około 20% szybszy niżsklearn.utils.shuffle(df)
przy użyciu tego samego kodu powyżej. Lub możesz zrobić,sklearn.utils.shuffle(ndarray)
aby uzyskać inny wynik.(Nie mam wystarczającej reputacji, aby skomentować to w pierwszym poście, więc mam nadzieję, że ktoś inny może to dla mnie zrobić). Pojawiła się obawa, że pierwsza metoda:
wykonałem głęboką kopię lub po prostu zmieniłem ramkę danych. Uruchomiłem następujący kod:
a moje wyniki to:
co oznacza, że metoda nie zwraca tego samego obiektu, jak zasugerowano w ostatnim komentarzu. Tak więc ta metoda rzeczywiście wykonuje pomieszaną kopię .
źródło
id
s) obiekt podstawowy nie jest kopiowany. Innymi słowy, operacja jest efektywnie zapamiętywana (chociaż nie jest to oczywiste).Co jest również przydatne, jeśli używasz go do uczenia maszynowego i chcesz oddzielić zawsze te same dane, możesz użyć:
zapewnia to, że Twój losowy wybór zawsze będzie powtarzalny
źródło
AFAIK najprostszym rozwiązaniem jest:
źródło
np.random.permutation
: „... Jeśli x jest tablicą, wykonaj kopię i losowo losuj elementy”. DokumentacjaDataFrame.reindex
: „ Nowy obiekt jest tworzony, chyba że nowy indeks jest równoważny bieżącemu i copy = False”. Tak więc odpowiedź jest całkowicie bezpieczna (choć tworzenie kopii).np.random.permutation says
i w zależności od wersji numpy, otrzymujesz efekt, który opisałem lub ten, o którym wspomniałeś. W przypadku numpy> 1.15.0, tworzenia ramki danych i wykonywania zwykłegonp.random.permutation(df.index)
, indeksy w oryginalnym pliku df zmieniają się. To samo nie dotyczy numpy == 1.14.6. Dlatego bardziej niż kiedykolwiek powtarzam moje ostrzeżenie: ten sposób robienia rzeczy jest niebezpieczny z powodu nieprzewidzianych efektów ubocznych i zależności wersji.Index
typu ... W każdym razie moje zalecenia / ostrzeżeniaprzetasuj ramkę danych pandy, pobierając przykładową tablicę w tym indeksie przypadków i losowo uporządkuj jej kolejność, a następnie ustaw tablicę jako indeks ramki danych. Teraz posortuj ramkę danych według indeksu. Oto twoja przetasowana ramka danych
wynik
Wstaw ramkę danych w miejscu mojego w powyższym kodzie.
źródło
Oto inny sposób:
df['rnd'] = np.random.rand(len(df)) df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
źródło