在pandas中改组/置换DataFrame

66 python numpy pandas

在pandas中,按行或按列对数据帧进行随机播放的简单有效方法是什么?即如何编写一个函数shuffle(df, n, axis=0),它接受一个数据帧,一些shuffle n和一个轴(axis=0是行,axis=1是列),并返回已经洗牌n次数的数据帧的副本.

编辑:关键是在不破坏数据帧的行/列标签的情况下执行此操作.如果你只是洗牌df.index,那就失去了所有的信息.我希望结果df与原始相同,除了行的顺序或列的顺序不同.

编辑2:我的问题不清楚.当我说洗牌行时,我的意思是每行独立洗牌.因此,如果您有两列,a并且b我希望每行都自行进行洗牌,那么如果您只是重新排序每一行,那么您之间a和之间的关联就不b一样了.就像是:

for 1...n:
  for each col in df: shuffle column
return new_df
Run Code Online (Sandbox Code Playgroud)

但希望比天真循环更有效.这对我不起作用:

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)
Run Code Online (Sandbox Code Playgroud)

Zel*_*ny7 197

使用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
Run Code Online (Sandbox Code Playgroud)

  • +1,因为这正是我所寻找的(即使事实证明它不是OP想要的) (25认同)
  • 也可以使用`df.iloc [np.random.permutation(np.arange(len(df)))]`如果有傻瓜和东西(并且mi可能更快). (4认同)
  • 不错的方法.有没有办法在现场做到这一点? (3认同)
  • 对我来说(Python v3.6和Pandas v0.20.1)我不得不用'df.set_index(np.random.permutation(df.index)'替换`df.reindex(np.random.permutation(df.index))` )`以获得理想的效果. (2认同)

W.P*_*ill 84

采样随机化,因此只需对整个数据帧进行采样.

df.sample(frac=1)
Run Code Online (Sandbox Code Playgroud)

  • 注意,如果您尝试使用此方法重新分配列,则必须执行df ['column'] = df ['column']。sample(frac = 1).reset_index(drop = True)` (5认同)

roo*_*oot 33

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
Run Code Online (Sandbox Code Playgroud)

  • `df.apply(np.random.permutation)`也有效 (25认同)
  • **警告**我认为``df.apply(np.random.permutation)``可以作为解决方案``df.reindex(np.random.permutation(df.index))``看起来更整洁,但是实际上他们表现得不一样 后者维持同一行的列之间的关联,前者则不然.当然,我的误解,但希望它能使其他人免于同样的错误. (14认同)
  • 如何区分行重排和列重排? (2认同)

Fra*_*urt 18

您可以使用 sklearn.utils.shuffle()(需要 sklearn 0.16.1或更高版本来支持Pandas数据框):

# 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))
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用df.reset_index()重置索引列,如果需要:

df = df.reset_index(drop=True)
print('\n\ndf: {0}'.format(df)
Run Code Online (Sandbox Code Playgroud)

输出:

df:    A  B
0  1  1
1  0  0
2  4  4
3  2  2
4  3  3
Run Code Online (Sandbox Code Playgroud)


Ted*_*rou 7

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
Run Code Online (Sandbox Code Playgroud)

您必须使用,.value以便您返回一个 numpy 数组而不是一个系列,否则返回的系列将与原始 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
Run Code Online (Sandbox Code Playgroud)


Eva*_*mir 6

从文档中使用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
Run Code Online (Sandbox Code Playgroud)