Programing

DataFrame 행 섞기

lottogame 2020. 3. 9. 08:04
반응형

DataFrame 행 섞기


다음과 같은 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은 csv 파일에서 읽습니다. Type1이 있는 모든 행 은 맨 위에 있고, Type2가있는 행, Type3이 있는 행 등이 있습니다.

모든 행 Type이 혼합 되도록 DataFrame 행의 순서를 섞고 싶습니다 . 가능한 결과는 다음과 같습니다.

    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
...

어떻게하면 되나요?


팬더 로이 작업을 수행하는 관용적 인 방법은 .sample데이터 프레임 방법 을 사용하는 것입니다.

df.sample(frac=1)

frac있도록 키워드 인수 지정 행의 분수는, 랜덤 샘플 반환 frac=1수단은 (임의의 순서로)의 모든 행을 반환한다.

참고 : 데이터 프레임을 제자리에 섞고 인덱스를 재설정하려면 다음과 같이하십시오.

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

여기서 지정 drop=True하면 .reset_index이전 색인 항목이 포함 된 열이 작성되지 않습니다.

후속 참고 사항 : 위 작업이 제 위치 있는 것처럼 보이지는 않지만 파이썬 / 팬더는 셔플 된 객체에 대해 다른 malloc을 수행하지 않을만큼 똑똑합니다. 즉, 참조 객체가 변경 되었지만 (즉, id(df_old)와 같지 않음 id(df_new)) 기본 C 객체는 여전히 동일합니다. 이것이 사실임을 보여주기 위해 간단한 메모리 프로파일 러를 실행할 수 있습니다.

$ python3 -m memory_profiler .\test.py
Filename: .\test.py

Line #    Mem usage    Increment   Line Contents
================================================
     5     68.5 MiB     68.5 MiB   @profile
     6                             def shuffle():
     7    847.8 MiB    779.3 MiB       df = pd.DataFrame(np.random.randn(100, 1000000))
     8    847.9 MiB      0.1 MiB       df = df.sample(frac=1).reset_index(drop=True)


당신은 단순히 이것을 위해 sklearn을 사용할 수 있습니다

from sklearn.utils import shuffle
df = shuffle(df)

셔플 된 인덱스로 인덱싱하여 데이터 프레임의 행을 셔플 할 수 있습니다. 이를 위해 다음을 사용할 수 있습니다 np.random.permutation(그러나 np.random.choice가능할 수도 있습니다).

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

예제와 같이 인덱스 번호를 1, 2, .., n으로 유지하려면 인덱스를 재설정하면됩니다. df_shuffled.reset_index(drop=True)


TL; DR : np.random.shuffle(ndarray)작업을 수행 할 수 있습니다.
따라서 귀하의 경우

np.random.shuffle(DataFrame.values)

DataFrame후드 아래에서 NumPy ndarray를 데이터 홀더로 사용합니다. ( DataFrame 소스 코드 에서 확인할 수 있습니다 )

따라서를 사용하면 np.random.shuffle()다차원 배열의 첫 번째 축을 따라 배열을 섞습니다. 그러나 DataFrame유골의 색인 은 뒤섞이지 않았다.

그러나 고려해야 할 몇 가지 사항이 있습니다.

  • 함수는 none을 반환합니다. 원래 객체의 사본을 유지하려면 함수에 전달하기 전에 수행해야합니다.
  • sklearn.utils.shuffle()tj89 사용자가 제안한대로 random_state출력을 제어하는 ​​다른 옵션과 함께 지정할 수 있습니다 . 당신은 그것을 개발 목적으로 원할 수 있습니다.
  • sklearn.utils.shuffle()더 빠르다. 그러나의 축 정보 (인덱스, 열) SHUFFLE 것 DataFrame와 함께 ndarray이 포함되어 있습니다.

벤치 마크 결과

사이 sklearn.utils.shuffle()np.random.shuffle().

ndarray

nd = sklearn.utils.shuffle(nd)

0.10793248389381915 초 8 배 더 빠름

np.random.shuffle(nd)

0.8897626010002568 초

DataFrame

df = sklearn.utils.shuffle(df)

0.3183923360193148 초 3 배 더 빠름

np.random.shuffle(df.values)

0.9357550159329548 초

결론 : ndarray와 함께 섞여 축 정보 (색인, 열)에 괜찮다면을 사용하십시오 sklearn.utils.shuffle(). 그렇지 않으면np.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)


(최고의 게시물에 이것을 언급 할만 큼 평판이 충분하지 않으므로 다른 사람이 나를 위해 그렇게 할 수 있기를 바랍니다.) 첫 번째 방법은 다음과 같은 우려가 제기되었습니다.

df.sample(frac=1)

딥 카피를 만들거나 데이터 프레임을 변경했습니다. 다음 코드를 실행했습니다.

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

내 결과는 다음과 같습니다.

0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70

이는 마지막 주석에서 제안한 것처럼 메소드가 동일한 객체를 반환 하지 않음 을 의미합니다 . 따라서이 방법은 실제로 뒤섞인 사본을 만듭니다.


AFAIK 가장 간단한 해결책은 다음과 같습니다.

df_shuffled = df.reindex(np.random.permutation(df.index))

이 경우 인덱스 로 샘플 배열을 가져와 팬더 데이터 프레임을 섞고 순서를 랜덤 화 한 다음 배열을 데이터 프레임 인덱스로 설정하십시오. 이제 인덱스에 따라 데이터 프레임을 정렬하십시오. 셔플 된 데이터 프레임으로갑니다.

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()

산출

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

위의 코드에서 내 자리에 데이터 프레임을 삽입하십시오.


유용한 정보, Machine_learning에 사용하고 항상 동일한 데이터를 분리하려면 다음을 사용할 수 있습니다.

df.sample(n=len(df), random_state=42)

이것은 무작위 선택을 항상 복제 가능하게 유지합니다.


다른 방법은 다음과 같습니다.

df['rnd'] = np.random.rand(len(df)) df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)

참고 URL : https://stackoverflow.com/questions/29576430/shuffle-dataframe-rows

반응형