Добавление ряда в DataFrame приводит к странному поведению

#python #pandas #dataframe #machine-learning

#python #панды #dataframe #машинное обучение

Вопрос:

Мой набор данных составляет 307 511 строк, а набор тестов — 48 744. Я объединил их в один dataframe (с именем ‘data’), который составляет 356255 строк.

Я создал ряд, который указывает, принадлежит ли элемент к обучающему или тестовому набору.

 trainlen = pd.Series([1]*len(train) [0]*len(test))
  

Его длина составляет 356255, как и ожидалось.

Когда я добавляю его в набор данных, я получаю странное поведение:

 data = pd.concat([train,test])
data['isTrain'] = trainlen
  

В то время trainlen.sum() как возвращает 307 511 (как и должно быть), data.isTrain.sum() возвращает 356 255.

Это только тогда, когда я использую «значения»:

 data['isTrain'] = trainlen.values
  

Это data.isTrain.sum() возвращает 307511.

Можете ли вы объяснить, почему это происходит?

Ответ №1:

Проблема с индексами. Когда вы используете concat метод для двух фреймов данных, индексы будут объединены, генерируя что-то подобное для индекса вашего df:

 [0, 1, 2, ..., 307510, 0, 1, 2, 3, ... 48743]
  

Как вы можете видеть, индексы снова начинаются с 0 в какой-то момент. Но поскольку у вашей серии также есть индексы, когда вы выполняете назначение следующим образом:

 data['isTrain'] = trainlen # I am doing an assignment with a Series object that contains also indexes!
  

данные в ряду будут соответствовать только индексам, присутствующим в вашем dataframe, создавая список только из ‘1. (для вашей серии значения, соответствующие индексам [0, 1, 2, 3, … 48743] являются ‘1‘)

ваш df будет примерно таким

         inst  isTrain
0          0        1
1          1        1
2          2        1
3          3        1
4          4        1
...      ...      ...
48739  48739        1
48740  48740        1
48741  48741        1
48742  48742        1
48743  48743        1
  

Вы видите, что индексы неверны? Но если вы измените индексы вашего df перед назначением, это сработает:

 data.index = [i for i in range(len(data))] # here I am changingresetting the indexes
data['isTrain'] = trainlen

print(trainlen.sum())
print(data.isTrain.sum())
  

теперь индексы и значения верны!

          inst  isTrain
0           0        1
1           1        1
2           2        1
3           3        1
4           4        1
...       ...      ...
356250  48739        0
356251  48740        0
356252  48741        0
356253  48742        0
356254  48743        0
  

Когда вы используете trainlen.values вместо этого, вы не используете индексы рядов. Таким образом, вы в безопасности при назначении!

Комментарии:

1. Большое спасибо за ваши подробные объяснения. Я многому научился.