Wiersze ramki danych Shuffle

Mam następujący 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
...

Ramka danych jest odczytywana z pliku csv. Wszystkie wiersze, które mają Type 1 znajdują się na górze, następnie wiersze z Type 2, a następnie wiersze z Type 3, itd.

Chciałbym przetasować wiersze ramki danych, aby wszystkie Type były mieszane. Możliwy wynik 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 widać z wyniku, kolejność wierszy jest tasowana, ale kolumny pozostają takie same. Nie wiem, czy jasno to wyjaśniam. Niech ja wiem, Jeśli nie.

Jak mogę to osiągnąć?

Author: JNevens, 2015-04-11

7 answers

Bardziej idiomatycznym sposobem na zrobienie tego z pand jest użycie metody .sample ramki danych, czyli

df.sample(frac=1)

Argument słowa kluczowego frac określa ułamek wierszy, które mają być zwrócone w próbie losowej, więc frac=1 oznacza zwracanie wszystkich wierszy (w losowej kolejności).

Uwaga: Jeśli chcesz przetasować ramkę danych na miejscu i zresetować indeks, możesz zrobić np.

df = df.sample(frac=1).reset_index(drop=True)

tutaj podanie drop=True uniemożliwia .reset_index Tworzenie kolumny zawierającej Stary indeks pozycji.

 348
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-27 09:18:11

Możesz po prostu użyć sklepu do tego

from sklearn.utils import shuffle
df = shuffle(df)
 101
Author: tj89,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-24 07:42:10

Możesz przetasować wiersze ramki danych, indeksując indeks tasowany. W tym celu możesz np. użyć np.random.permutation (ale np.random.choice jest również możliwość):

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

Jeśli chcesz, aby indeks był ponumerowany od 1, 2, .., n jak w twoim przykładzie, możesz po prostu zresetować indeks: df_shuffled.reset_index(drop=True)

 44
Author: joris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-11 10:26:59

TL; DR: np.random.shuffle(ndarray) poradzi sobie.
Więc w Twoim przypadku

np.random.shuffle(DataFrame.values)

Bazując na moim zrozumieniu, DataFrame, pod maską, używa NumPy ndarray jako nośnika danych. Możesz sprawdzić z DataFrame kod źródłowy . Więc jeśli używasz np.random.shuffle(), to tasuje tablicę wzdłuż pierwszej osi wielowymiarowej tablicy. Ale kolumny-mądry pozostaje ten sam.

Istnieją pewne ograniczenia.

  • funkcja zwraca none. In case you chcesz zachować kopię oryginalnego obiektu, musisz to zrobić przed przejściem do funkcji.
  • sklearn.utils.shuffle() użytkownik tj89 zasugerował, może wyznaczyć random_state wraz z inną opcją sterowania wyjściami. Możesz chcieć to dla dev purpose.

Benchmark result

Pomiędzy sklearn.utils.shuffle() oraz np.random.shuffle().

Ndarray

nd = sklearn.utils.shuffle(nd)

0.10793248389381915 sek. 8x szybciej

np.random.shuffle(nd)

0.8897626010002568 sec

DataFrame

df = sklearn.utils.shuffle(df)

0.3183923360193148 sek. 3x szybciej

np.random.shuffle(df.values)', setup=setup, number=1000)

0.9357550159329548 sek

Wniosek: użycie sklearn.utils.shuffle(), jeśli to możliwe.

Użyty kod

setup = '''
import numpy as np
import pandas as pd
from sklearn.utils import shuffle
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)

Pythonbenchmarking

 13
Author: haku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-23 06:07:48

(nie mam wystarczającej reputacji, aby skomentować to na top post, więc mam nadzieję, że ktoś inny może to zrobić za mnie.) pojawiły się obawy, że pierwsza metoda:

df.sample(frac=1)

Zrobiłem głęboką kopię lub po prostu zmieniłem ramkę danych. Uruchomiłem następujący kod:

print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))

A moje wyniki były:

0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70

Co oznacza, że metoda Nie zwraca ten sam obiekt, jak sugerowano w ostatnim komentarzu. Tak więc ta metoda rzeczywiście powoduje tasowanie Kopia .

 3
Author: NotANumber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 16:31:32

AFAIK najprostszym rozwiązaniem jest:

df_shuffled = df.reindex(np.random.permutation(df.index))
 1
Author: Ido Cohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-27 13:09:13

Przetasuj ramkę danych pandy, pobierając przykładową tablicę w tym przypadku index i Losuj jej kolejność, a następnie Ustaw tablicę jako indeks ramki danych. Teraz posortuj ramkę danych według indeksu. Here goes your shuffled 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()

Wyjście

    a   b
0   2   6
1   1   5
2   3   7
3   4   8

Wstaw ramkę danych w miejsce mojego w powyższym kodzie .

 0
Author: Abhilash Reddy Yammanuru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-13 11:28:40