我的训练集有307,511行,测试集有48,744行。我将它们合并成一个名为’data’的数据框,总共有356,255行。
我创建了一个系列,用于标记项目是属于训练集还是测试集。
trainlen = pd.Series([1]*len(train)+[0]*len(test))
它的长度如预期般为356,255。
当我将其添加到数据集中时,出现了奇怪的行为:
data = pd.concat([train,test])data['isTrain'] = trainlen
虽然trainlen.sum()
返回了307,511(如预期),但data.isTrain.sum()
返回了356,255。
只有当我使用’values’时:
data['isTrain'] = trainlen.values
data.isTrain.sum()
才返回307,511。
您能解释这是为什么吗?
回答:
问题出在索引上。当您使用concat
方法合并两个数据框时,索引会被拼接,生成类似这样的索引:
[0, 1, 2, ..., 307510, 0, 1, 2, 3, ... 48743]
如您所见,索引在某个点会从0重新开始。但因为您的系列也有索引,当您这样赋值时:
data['isTrain'] = trainlen # 我正在使用一个也包含索引的Series对象进行赋值!
系列中的数据只会匹配数据框中存在的索引,生成一个全是’1’的列表。(对于您的系列,与索引[0, 1, 2, 3, … 48743]匹配的值是’1’)
您的df会变成这样:
inst isTrain0 0 11 1 12 2 13 3 14 4 1... ... ...48739 48739 148740 48740 148741 48741 148742 48742 148743 48743 1
您能看到索引是错误的吗?但如果您在赋值前更改df的索引,它就会正常工作:
data.index = [i for i in range(len(data))] # 这里我在更改/重置索引data['isTrain'] = trainlenprint(trainlen.sum())print(data.isTrain.sum())
现在索引和值都是正确的!
inst isTrain0 0 11 1 12 2 13 3 14 4 1... ... ...356250 48739 0356251 48740 0356252 48741 0356253 48742 0356254 48743 0
当您使用trainlen.values
时,您没有使用系列的索引。因此在赋值时是安全的!