ProgramingTip

팬더에서 DataFrame 셔플 / 순열

bestdevel 2020. 11. 12. 19:25
반응형

팬더에서 DataFrame 셔플 / 순열


Pandas에서 행 또는 열로 데이터 프레임을 섞는 간단하고 방법은 무엇입니까? shuffle(df, n, axis=0), 데이터 프레임, 셔플 수 n및 축 ( axis=0행, axis=1열) 을 가져 오기 셔플 된 데이터 프레임의 복사본을 반환 하는 함수를 작성하는 방법 n입니다.

편집 : 핵심은 데이터 프레임의 행 / 열 레이블을 파괴하지 않고 수행하는 것입니다. 셔플 df.index하면 모든 정보가 증가합니다. df행 순서 나 열 순서가 다른 경우를 제외하고 결과 가 원본과 동일하기를 원합니다 .

Edit2 : 내 질문이 명확하지 않습니다. 행 셔플이라고하면 각 행을 독립적으로 셔플하는 것을 의미합니다. 두 개의 개의 열이있는 경우 ab, 각 행을 자체적으로 섞어서 각 행을 전체적으로 다시 정렬하는 것처럼 a모든 연관성을 갖지 않도록합니다 b. 다음과 같은 것 :

for 1...n:
  for each col in df: shuffle column
return new_df

그러나 순진한 루핑보다 처음입니다. 이것은 나를 위해 작동하지 않습니다.

def shuffle(df, n, axis=0):
        shuffled_df = df.copy()
        for k in range(n):
            shuffled_df.apply(np.random.shuffle(shuffled_df.values),axis=axis)
        return shuffled_df

df = pandas.DataFrame({'A':range(10), 'B':range(10)})
shuffle(df, 5)

In [16]: def shuffle(df, n=1, axis=0):     
    ...:     df = df.copy()
    ...:     for _ in range(n):
    ...:         df.apply(np.random.shuffle, axis=axis)
    ...:     return df
    ...:     

In [17]: df = pd.DataFrame({'A':range(10), 'B':range(10)})

In [18]: shuffle(df)

In [19]: df
Out[19]: 
   A  B
0  8  5
1  1  7
2  7  3
3  6  2
4  3  4
5  0  1
6  9  0
7  4  6
8  2  8
9  5  9

numpy의 random.permuation기능을 사용하십시오 .

In [1]: df = pd.DataFrame({'A':range(10), 'B':range(10)})

In [2]: df
Out[2]:
   A  B
0  0  0
1  1  1
2  2  2
3  3  3
4  4  4
5  5  5
6  6  6
7  7  7
8  8  8
9  9  9


In [3]: df.reindex(np.random.permutation(df.index))
Out[3]:
   A  B
0  0  0
5  5  5
6  6  6
3  3  3
8  8  8
7  7  7
9  9  9
1  1  1
2  2  2
4  4  4

샘플링은 무작위 화 전체 데이터 프레임을 샘플링하기 만하면됩니다.

df.sample(frac=1)

다음을 사용할 수 있습니다 ( 팬더-frame을 지원 데이터 하려면 sklearn 0.16.1 이상 필요 ) :sklearn.utils.shuffle()

# Generate data
import pandas as pd
df = pd.DataFrame({'A':range(5), 'B':range(5)})
print('df: {0}'.format(df))

# Shuffle Pandas data frame
import sklearn.utils
df = sklearn.utils.shuffle(df)
print('\n\ndf: {0}'.format(df))

출력 :

df:    A  B
0  0  0
1  1  1
2  2  2
3  3  3
4  4  4


df:    A  B
1  1  1
0  0  0
3  3  3
4  4  4
2  2  2

그런 다음 필요한 경우 고급 열을 사용할 수 있습니다.df.reset_index()

df = df.reset_index(drop=True)
print('\n\ndf: {0}'.format(df)

출력 :

df:    A  B
0  1  1
1  0  0
2  4  4
3  2  2
4  3  3

문서 사용에서 sample():

In [79]: s = pd.Series([0,1,2,3,4,5])

# When no arguments are passed, returns 1 row.
In [80]: s.sample()
Out[80]: 
0    0
dtype: int64

# One may specify either a number of rows:
In [81]: s.sample(n=3)
Out[81]: 
5    5
2    2
4    4
dtype: int64

# Or a fraction of the rows:
In [82]: s.sample(frac=0.5)
Out[82]: 
5    5
4    4
1    1
dtype: int64

@root의 대답을 약간 수정하고 원시 값을 직접 사용했습니다. 물론 이것은 멋진 인덱싱을 수행 할 수있는 능력을 잃는다는 것을 의미하지만 데이터를 섞는 데는 완벽하게 작동합니다.

In [1]: import numpy

In [2]: import pandas

In [3]: df = pandas.DataFrame({"A": range(10), "B": range(10)})    

In [4]: %timeit df.apply(numpy.random.shuffle, axis=0)
1000 loops, best of 3: 406 µs per loop

In [5]: %%timeit
   ...: for view in numpy.rollaxis(df.values, 1):
   ...:     numpy.random.shuffle(view)
   ...: 
10000 loops, best of 3: 22.8 µs per loop

In [6]: %timeit df.apply(numpy.random.shuffle, axis=1)
1000 loops, best of 3: 746 µs per loop

In [7]: %%timeit                                      
for view in numpy.rollaxis(df.values, 0):
    numpy.random.shuffle(view)
   ...: 
10000 loops, best of 3: 23.4 µs per loop

numpy.rollaxis우리는 (열) 첫 번째 차원을 따라 셔플하려는 경우, 즉, 첫 번째 차원에 지정된 축을 제공하고 나머지 크기와 배열을 통해 우리에게의를 반복 처리를하자, 우리는 그래서, 전면에 두 번째을 롤백해야 할 첫 번째 차원에 대한 뷰에 셔플 링을 적용합니다.

In [8]: numpy.rollaxis(df, 0).shape
Out[8]: (10, 2) # we can iterate over 10 arrays with shape (2,) (rows)

In [9]: numpy.rollaxis(df, 1).shape
Out[9]: (2, 10) # we can iterate over 2 arrays with shape (10,) (columns)

그런 다음 최종 함수는 트릭을 사용하여 함수를 축에 적용하기위한 기대치와 일치하도록 결과를 가져옵니다.

def shuffle(df, n=1, axis=0):     
    df = df.copy()
    axis = int(not axis) # pandas.DataFrame is always 2D
    for _ in range(n):
        for view in numpy.rollaxis(df.values, axis):
            numpy.random.shuffle(view)
    return df

더 유용 할 수 있습니다.

def shuffle(df):
    index = list(df.index)
    random.shuffle(index)
    df = df.ix[index]
    df.reset_index()
    return df

새 색인을 사용하여 새 df를 선택합니다.


Pandas의 간단한 해결책은 sample각 열에서 독립적으로 메서드 를 사용하는 것입니다. apply각 열을 반복하는 데 사용 합니다.

df = pd.DataFrame({'a':[1,2,3,4,5,6], 'b':[1,2,3,4,5,6]})
df

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

df.apply(lambda x: x.sample(frac=1).values)

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

.valueSeries가 아닌 numpy 배열을 반환하도록을 사용해야합니다. 그렇지 않으면 반환 된 Series가 원래 DataFrame에 정렬되어 사물을 변경하지 않습니다.

df.apply(lambda x: x.sample(frac=1))

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

나는이 질문에 대해 알고 pandasDF하지만 경우에 셔플 행에 의해 발생 후 열 이름이 문제가 더 이상하지 말고를 사용하는 흥미로운 일이 될 수있다, (열 순서가 변경되지 않은 행 순서 변경) np.array대신에, 다음, np.apply_along_axis()당신이 무엇을 할 것이다 를 찾고 있습니다.

이것이 수용 가능하다면 이것은 도움이 될 것입니다. 데이터가 섞이는 축을 쉽게 전환 할 수 있습니다.

팬더 데이터 프레임의 이름이 df이면 다음을 수행 할 수 있습니다.

  1. dataframe의 값을 함께 얻을 values = df.values,
  2. 생성 np.array에서을values
  3. 아래 표시된 방법을 적용하여 np.array행 또는 열 을 섞습니다.
  4. 셔플에서 새로운 (셔플) 팬더 df를 다시 만듭니다. np.array

원래 배열

a = np.array([[10, 11, 12], [20, 21, 22], [30, 31, 32],[40, 41, 42]])
print(a)
[[10 11 12]
 [20 21 22]
 [30 31 32]
 [40 41 42]]

행 순서 유지, 각 행 내에서 열 셔플

print(np.apply_along_axis(np.random.permutation, 1, a))
[[11 12 10]
 [22 21 20]
 [31 30 32]
 [40 41 42]]

열 순서를 유지하고 각 열 내에서 행을 섞습니다.

print(np.apply_along_axis(np.random.permutation, 0, a))
[[40 41 32]
 [20 31 42]
 [10 11 12]
 [30 21 22]]

원래 배열은 변경되지 않습니다.

print(a)
[[10 11 12]
 [20 21 22]
 [30 31 32]
 [40 41 42]]

다음은 DataFrame의 하위 집합 만 셔플하려는 경우 찾은 해결 방법입니다.

shuffle_to_index = 20
df = pd.concat([df.iloc[np.random.permutation(range(shuffle_to_index))], df.iloc[shuffle_to_index:]])

참고 URL : https://stackoverflow.com/questions/15772009/shuffling-permutating-a-dataframe-in-pandas

반응형