Добавить столбец в фрейм данных pandas


105

Наверное, это легко, но у меня есть следующие данные:

Во фрейме данных 1:

index dat1
0     9
1     5

Во фрейме данных 2:

index dat2
0     7
1     6

Мне нужен фрейм данных следующей формы:

index dat1  dat2
0     9     7
1     5     6

Я пробовал использовать этот appendметод, но получаю перекрестное соединение (т.е. декартово произведение).

Как правильно это сделать?


2
Вы пробовали joinметод?
— BrenBarn

1
data_frame_1 ['dat2'] = data_frame_2 ['dat2']
— lowtech

@lowtech: гарантирует ли это правильное объединение индексов?
— BenDundee

@BenDundee: да, это так
— lowtech

Ответы:


135

В общем, похоже, вы просто ищете соединение:

> dat1 = pd.DataFrame({'dat1': [9,5]})
> dat2 = pd.DataFrame({'dat2': [7,6]})
> dat1.join(dat2)
   dat1  dat2
0     9     7
1     5     6

45
Или pd.concat([dat1, dat2], axis=1)в этом случае.
— DSM

2
@BenDundee Join и concat используют много одного и того же кода под капотом, поэтому «правильный» способ, вероятно, имеет значение только при рассмотрении крайних случаев. Например, здесь, если у обоих DataFrames есть столбец «данные», соединение не удастся , тогда как объединение даст вам два столбца с именем «данные».
— U2EF1

@ U2EF1: Я говорил о вашем ответе против моего. Всегда есть N способов снять шкуру с кошки :)
— BenDundee

@BenDundee Понятно. Этот метод отбрасывает уникальный индекс и имеет еще более странные побочные эффекты в более сложных случаях. Например, если бы у меня было два столбца с именем «данные», при группировке / суммировании началось бы суммирование различных столбцов данных, что почти наверняка не то, что вам нужно. Строковые данные будут объединены.
— U2EF1

1
Как указывает @ jeremy-z, очень важно сбросить индексы в обоих наборах данных, если они не имеют одного и того же индекса. В противном случае вы получите один набор данных с большим количеством строк NaN.
— Israel

57

Вы также можете использовать:

dat1 = pd.concat([dat1, dat2], axis=1)

1
В случае , если вы столкнулись InvalidIndexError: Reindexing only valid with uniquely valued Index objects , вы можете использовать:pd.concat([dat1.reset_index(), dat2], axis=1)
— beyondfloatingpoint

40

Как join()и concat()способ может решить эту проблему. Однако есть одно предупреждение, которое я должен упомянуть: сбросьте индекс перед вами join()или concat()если вы пытаетесь иметь дело с некоторым фреймом данных, выбирая некоторые строки из другого DataFrame.

В одном примере ниже показано интересное поведение соединения и объединения:

dat1 = pd.DataFrame({'dat1': range(4)})
dat2 = pd.DataFrame({'dat2': range(4,8)})
dat1.index = [1,3,5,7]
dat2.index = [2,4,6,8]

# way1 join 2 DataFrames
print(dat1.join(dat2))
# output
   dat1  dat2
1     0   NaN
3     1   NaN
5     2   NaN
7     3   NaN

# way2 concat 2 DataFrames
print(pd.concat([dat1,dat2],axis=1))
#output
   dat1  dat2
1   0.0   NaN
2   NaN   4.0
3   1.0   NaN
4   NaN   5.0
5   2.0   NaN
6   NaN   6.0
7   3.0   NaN
8   NaN   7.0

#reset index 
dat1 = dat1.reset_index(drop=True)
dat2 = dat2.reset_index(drop=True)
#both 2 ways to get the same result

print(dat1.join(dat2))
   dat1  dat2
0     0     4
1     1     5
2     2     6
3     3     7


print(pd.concat([dat1,dat2],axis=1))
   dat1  dat2
0     0     4
1     1     5
2     2     6
3     3     7

Хорошо сказано и хорошее замечание. Я попробовал без сброса индекса и сгенерировал много NULLS
— Ананд

Без выполнения шага сброса мои данные выглядели нормально и хорошо, но, очевидно, что-то не работало за кулисами. Спасибо, что указали на это! После перезагрузки моя модель заработала!
— Ionuț Ciuta

Это должен быть принятый ответ! Он всегда генерирует NaN, если мы не сбрасываем индекс.
— Шривацан

Этот шаг меня спас. Я пытался понять, почему concat и join выкидывают много NaN. Спасибо, что поделились этим.
— Густаво Роттжеринг,


-4

Просто вопрос правильного поиска в Google:

data = dat_1.append(dat_2)
data = data.groupby(data.index).sum()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.