JNe*_*ens 345 python shuffle permutation dataframe pandas
我有以下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
...
Run Code Online (Sandbox Code Playgroud)
从csv文件中读取DataFrame.所有具有Type
1的行都在顶部,其次是具有Type
2 的行,然后是具有Type
3 的行等.
我想改组DataFrame的行,以便所有的行Type
都是混合的.可能的结果可能是:
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
...
Run Code Online (Sandbox Code Playgroud)
从结果中可以看出,行的顺序是混洗的,但列保持不变.我不知道我是否清楚地解释了这一点.如果我不知道,请告诉我.
我怎样才能做到这一点?
Kri*_*ris 658
使用pandas执行此操作的更惯用方法是使用.sample
数据框的方法,即
df.sample(frac=1)
Run Code Online (Sandbox Code Playgroud)
的frac
关键字参数指定的行的分数的随机样本中返回,所以frac=1
装置返回所有行(随机顺序).
注意: 如果您希望就地对数据帧进行随机播放并重置索引,则可以执行以下操作:
df = df.sample(frac=1).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)
这里,指定drop=True
阻止.reset_index
创建包含旧索引条目的列.
tj8*_*j89 184
你可以简单地使用sklearn
from sklearn.utils import shuffle
df = shuffle(df)
Run Code Online (Sandbox Code Playgroud)
jor*_*ris 52
您可以通过使用混洗索引进行索引来对数据帧的行进行随机播放.为此,您可以使用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
Run Code Online (Sandbox Code Playgroud)
如果要保持索引编号为1,2,..,n,如示例所示,则只需重置索引即可: df_shuffled.reset_index(drop=True)
hak*_*aku 34
TL; DR:np.random.shuffle(ndarray)
可以完成这项工作.
所以,在你的情况下
np.random.shuffle(DataFrame.values)
Run Code Online (Sandbox Code Playgroud)
DataFrame
引擎盖下,使用NumPy ndarray作为数据持有者.(您可以从DataFrame源代码中查看)
因此,如果您使用np.random.shuffle()
,它将沿着多维数组的第一轴对阵列进行混洗.但DataFrame
保持不变的指数.
但是,有一些要考虑的问题.
sklearn.utils.shuffle()
用户tj89建议,可以指定random_state
另一个选项来控制输出.您可能希望将其用于开发目的.sklearn.utils.shuffle()
是比较快的.但洗牌的轴信息(索引,列)DataFrame
与沿ndarray
它包含的内容.之间sklearn.utils.shuffle()
和np.random.shuffle()
.
nd = sklearn.utils.shuffle(nd)
Run Code Online (Sandbox Code Playgroud)
0.10793248389381915秒 快了8倍
np.random.shuffle(nd)
Run Code Online (Sandbox Code Playgroud)
0.8897626010002568秒
df = sklearn.utils.shuffle(df)
Run Code Online (Sandbox Code Playgroud)
0.3183923360193148秒 快3倍
np.random.shuffle(df.values)
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
PV8*_*PV8 14
还有什么有用的,如果您将它用于 Machine_learning 并希望始终分离相同的数据,您可以使用:
df.sample(n=len(df), random_state=42)
Run Code Online (Sandbox Code Playgroud)
这可以确保您的随机选择始终可复制
小智 11
(我没有足够的声誉在最高职位发表评论,所以我希望其他人可以为我做这件事.)有人担心第一种方法:
df.sample(frac=1)
Run Code Online (Sandbox Code Playgroud)
做了一个深层副本或只是改变了数据帧.我运行了以下代码:
print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))
Run Code Online (Sandbox Code Playgroud)
我的结果是:
0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70
Run Code Online (Sandbox Code Playgroud)
这意味着该方法不会返回相同的对象,如上一条评论中所建议的那样.所以这个方法确实可以制作一个混乱的副本.
以下可能是其中一种方式:
dataframe = dataframe.sample(frac=1, random_state=42).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)
在哪里
frac=1表示数据帧的所有行
random_state=42表示在每次执行中保持相同的顺序
reset_index(drop=True)表示重新初始化随机数据帧的索引
AFAIK 最简单的解决方案是:
df_shuffled = df.reindex(np.random.permutation(df.index))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
272802 次 |
最近记录: |