Dołącz kolumnę do ramki danych pandy


104

Prawdopodobnie jest to łatwe, ale mam następujące dane:

W ramce danych 1:

index dat1
0     9
1     5

W ramce danych 2:

index dat2
0     7
1     6

Chcę ramkę danych o następującym formularzu:

index dat1  dat2
0     9     7
1     5     6

Próbowałem użyć tej appendmetody, ale otrzymałem sprzężenie krzyżowe (tj. Iloczyn kartezjański).

Jaki jest właściwy sposób, aby to zrobić?


2
Czy wypróbowałeś joinmetodę?
BrenBarn

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

@lowtech: czy zapewnia to prawidłowe sparowanie indeksów?
BenDundee,

@BenDundee: tak, to prawda
lowtech

Odpowiedzi:


132

Ogólnie wydaje się, że szukasz tylko dołączenia:

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

45
Albo pd.concat([dat1, dat2], axis=1)w tym przypadku.
DSM,

2
@BenDundee Dołącz i konkatuj, używaj dużo tego samego kodu pod maską, więc „właściwy” sposób ma znaczenie tylko wtedy, gdy weźmiesz pod uwagę skrajne przypadki. Na przykład tutaj, gdyby obie ramki DataFrames miały kolumnę „dane”, łączenie nie powiodło się , podczas gdy konkatowanie dałoby dwie kolumny o nazwie „dane”.
U2EF1

@ U2EF1: Mówiłem o twojej odpowiedzi w porównaniu z moją. Zawsze jest N sposobów na
oskórowanie

@BenDundee Widzę. Ta metoda odrzuca jednak unikalny indeks i ma jeszcze dziwniejsze skutki uboczne w bardziej skomplikowanych przypadkach. Na przykład gdybym miał dwie kolumny o nazwie „dane”, grupowanie / sumowanie zaczęłoby sumować różne kolumny danych, co prawie na pewno nie jest tym, czego chcesz. Dane ciągów zostałyby połączone.
U2EF1

1
Jak wskazał @ jeremy-z, bardzo ważne jest zresetowanie indeksów w obu zbiorach danych, jeśli nie mają one tego samego indeksu. W przeciwnym razie otrzymasz jeden zestaw danych z wieloma wierszami NaN.
Israel Varea

57

Możesz także użyć:

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

1
Jeśli napotkasz InvalidIndexError: Reindexing only valid with uniquely valued Index objects , możesz użyć:pd.concat([dat1.reset_index(), dat2], axis=1)
behindfloatingpoint

40

Obie join()i concat()sposób mogą rozwiązać problem. Jest jednak jedno ostrzeżenie, o którym muszę wspomnieć: zresetuj indeks przed tobą join()lub concat()jeśli próbujesz poradzić sobie z jakąś ramką danych, wybierając niektóre wiersze z innej ramki DataFrame.

Jeden przykład poniżej pokazuje kilka interesujących zachowań łączenia i łączenia:

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

Dobrze powiedziane i słuszne. Próbowałem bez resetowania indeksu i wygenerowałem całą masę NULLS
Anand

Bez wykonywania kroku resetowania moje dane wyglądały dobrze i dobrze, ale oczywiście coś nie działało dobrze za kulisami. Dzięki za zwrócenie uwagi! Reset sprawił, że mój model zaczął działać!
Ionuț Ciuta

To powinna być akceptowana odpowiedź! Zawsze generuje NaN, jeśli nie resetujemy indeksu.
Srivatsan

Ten krok mnie uratował. Próbowałem zrozumieć, dlaczego zarówno concat, jak i join rzucają dużo NaN. Dzięki za udostępnienie tego.
Gustavo Rottgering


-3

Tylko kwestia odpowiedniego wyszukiwania w Google:

data = dat_1.append(dat_2)
data = data.groupby(data.index).sum()
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.