最小例子:
请考虑此数据框temp
:
temp = pd.DataFrame({"A":[1,2,3,4,5,6,7,8,9,10],"B":[2,3,4,5,6,7,8,9,10,11],"C":[3,4,5,6,7,8,9,10,11,12]})
>>> temp
A B C
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
5 6 7 8
6 7 8 9
7 8 9 10
8 9 10 11
9 10 11 12
现在,尝试在for循环中一次洗牌每一列。
>>> for i in temp.columns:
... np.random.shuffle(temp.loc[:,i])
... print(temp)
...
A B C
0 8 2 3
1 3 3 4
2 9 4 5
3 6 5 6
4 4 6 7
5 10 7 8
6 7 8 9
7 1 9 10
8 2 10 11
9 5 11 12
A B C
0 8 7 3
1 3 9 4
2 9 8 5
3 6 10 6
4 4 4 7
5 10 11 8
6 7 5 9
7 1 3 10
8 2 2 11
9 5 6 12
A B C
0 8 7 6
1 3 9 8
2 9 8 4
3 6 10 10
4 4 4 7
5 10 11 11
6 7 5 5
7 1 3 3
8 2 2 12
9 5 6 9
这很有效。
具体示例:
现在,如果我想获得此数据框的一部分,出于培训和测试目的,那么我将使用train_test_split
中的sklearn.model_selection
函数。
>>> from sklearn.model_selection import train_test_split
>>> temp = pd.DataFrame({"A":[1,2,3,4,5,6,7,8,9,10],"B":[2,3,4,5,6,7,8,9,10,11],"C":[3,4,5,6,7,8,9,10,11,12]})
>>> y = [i for i in range(16,26)]
>>> len(y)
10
>>> X_train,X_test,y_train,y_test = train_test_split(temp,y,test_size=0.2)
>>> X_train
A B C
2 3 4 5
6 7 8 9
8 9 10 11
0 1 2 3
7 8 9 10
3 4 5 6
1 2 3 4
9 10 11 12
现在,我们已经获得了X_train
数据框。为了改组每一栏:
>>> for i in X_train.columns:
... np.random.shuffle(X_train.loc[:,i])
... print(X_train)
...
不幸的是,这会导致错误 错误:
sys:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "mtrand.pyx", line 4852, in mtrand.RandomState.shuffle
File "mtrand.pyx", line 4855, in mtrand.RandomState.shuffle
File "C:\Users\H.P\AppData\Local\Programs\Python\Python36\lib\site-packages\pandas\core\series.py", line 623, in __getitem__
result = self.index.get_value(self, key)
File "C:\Users\H.P\AppData\Local\Programs\Python\Python36\lib\site-packages\pandas\core\indexes\base.py", line 2560, in get_value
tz=getattr(series.dtype, 'tz', None))
File "pandas\_libs\index.pyx", line 83, in pandas._libs.index.IndexEngine.get_value
File "pandas\_libs\index.pyx", line 91, in pandas._libs.index.IndexEngine.get_value
File "pandas\_libs\index.pyx", line 139, in pandas._libs.index.IndexEngine.get_loc
File "pandas\_libs\hashtable_class_helper.pxi", line 811, in pandas._libs.hashtable.Int64HashTable.get_item
File "pandas\_libs\hashtable_class_helper.pxi", line 817, in pandas._libs.hashtable.Int64HashTable.get_item
KeyError: 4
追踪问题及其解决方案:
在SettingWithCopyWarning
下,我发现了this问题,其中第一个答案就是这句话:
但是,它可以创建一个更新
data['amount']
副本的副本 你不会看到的。然后你会想知道它为什么不是 更新
但是,如果是这种情况,那么为什么代码适用于第一种情况?
答案中也给出了:
Pandas几乎在所有方法调用中都返回一个对象的副本。该 就地操作是一种有效的操作,但是在 一般不清楚数据是否正在修改和可能 可能在复制品上工作。
因此,我们可以使用np.random.shuffle
代替np.random.permutation
,而不是>>> for i in X_train.columns:
... X_train.loc[:,i] = np.random.permutation(X_train.loc[:,i])
... print(X_train)
...
。所以:
SettingWithCopyWarning
但是,我再次得到C:\Users\H.P\AppData\Local\Programs\Python\Python36\lib\site-packages\pandas\core\indexing.py:621: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
self.obj[item_labels[indexer[info_axis]]] = value
A B C
2 10 4 5
6 9 8 9
8 2 10 11
0 8 2 3
7 1 9 10
3 3 5 6
1 4 3 4
9 7 11 12
A B C
2 10 5 5
6 9 11 9
8 2 4 11
0 8 9 3
7 1 3 10
3 3 8 6
1 4 10 4
9 7 2 12
A B C
2 10 5 10
6 9 11 5
8 2 4 11
0 8 9 3
7 1 3 4
3 3 8 6
1 4 10 12
9 7 2 9
,答案也是。
train_test_split
这可能是一种解决方法。
SettingWithCopyWarning
时,为什么代码适用于第一种情况,而不适用于第二种情况?np.random.shuffle
时,为什么我仍然会收到<md-tabs>
<md-tab>
<md-tab-label>
<span ng-class="......">
Title
</span>
</md-tab-label>
<md-tab-body>
content
</md-tab-body>
</md-tab>
</md-tabs>
?答案 0 :(得分:2)
1.当我使用
train_test_split
时,为什么代码适用于第一种情况,而不是第二种情况?
因为train_test_split会对X_train
行进行洗牌。因此每列的索引不是范围而是一组值
您可以通过检查temp
和X_train
X_train.index
Int64Index([6, 8, 9, 5, 0, 2, 3, 4], dtype='int64')
temp.index
RangeIndex(start=0, stop=10, step=1)
在第一种情况下,与第二种情况不同,可以安全地将列视为一个数组。如果您将第二种情况中的代码更改为
for i in X_train.columns:
np.random.shuffle(X_train.loc[:,i].values)
print(X_train)
这不会导致错误。
请注意,在您呈现的情况下,随机播放将导致每列不同的随机播放。即数据点会混淆。
2.当我没有使用inplace shuffler
SettingWithCopyWarning
时,为什么我仍然得到np.random.shuffle
?
使用最新版本的pandas(0.22.0)
时,我没有收到警告建议请求:
- 是否有更好的(易于使用/无错误/更快)的方法来进行列改组?
醇>
我建议在axis=1
时使用样本,它会对列进行随机播放,样本数应该是列数。即X_train.shape[1]
X_train = X_train.sample(X_train.shape[1],axis=1)
In []: X_train.sample(X_train.shape[1],axis=1)
Out[]:
B A C
6 8 7 9
9 11 10 12
8 10 9 11
4 6 5 7
5 7 6 8
0 2 1 3
2 4 3 5
3 5 4 6
答案 1 :(得分:0)
我在使用 train_test_split 时也遇到了这个问题。我改用这个:
np.random.shuffle(x.iloc[:, i].values)
不知道为什么有效,但似乎解决了问题