Mesclar dois quadros de dados por índice

161

Oi, eu tenho os seguintes quadros de dados:

> df1
  id begin conditional confidence discoveryTechnique  
0 278    56       false        0.0                  1   
1 421    18       false        0.0                  1 

> df2
   concept 
0  A  
1  B

Como mesclar os índices para obter:

  id begin conditional confidence discoveryTechnique   concept 
0 278    56       false        0.0                  1  A 
1 421    18       false        0.0                  1  B

Eu pergunto porque é do meu entendimento que, merge()ou seja, df1.merge(df2)usa colunas para fazer a correspondência. De fato, fazendo isso, recebo:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 4618, in merge
    copy=copy, indicator=indicator)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 58, in merge
    copy=copy, indicator=indicator)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 491, in __init__
    self._validate_specification()
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 812, in _validate_specification
    raise MergeError('No common columns to perform merge on')
pandas.tools.merge.MergeError: No common columns to perform merge on

É uma má prática mesclar no índice? Isso é impossível? Nesse caso, como posso mudar o índice para uma nova coluna chamada "index"?

obrigado

brucezepplin
fonte
3
tente isto:df1.join(df2)
MaxU
E se você desejar ingressar no índice de um quadro de dados e em uma coluna do segundo quadro de dados. (Meu segundo dataframe tem uma coluna que corresponde aos indeces no primeiro DF).
mikey

Respostas:

322

Use merge, que é junção interna por padrão:

pd.merge(df1, df2, left_index=True, right_index=True)

Ou join, que é deixado unido por padrão:

df1.join(df2)

Ou concat, que é junção externa por padrão:

pd.concat([df1, df2], axis=1)

Amostras :

df1 = pd.DataFrame({'a':range(6),
                    'b':[5,3,6,9,2,4]}, index=list('abcdef'))

print (df1)
   a  b
a  0  5
b  1  3
c  2  6
d  3  9
e  4  2
f  5  4

df2 = pd.DataFrame({'c':range(4),
                    'd':[10,20,30, 40]}, index=list('abhi'))

print (df2)
   c   d
a  0  10
b  1  20
h  2  30
i  3  40

#default inner join
df3 = pd.merge(df1, df2, left_index=True, right_index=True)
print (df3)
   a  b  c   d
a  0  5  0  10
b  1  3  1  20

#default left join
df4 = df1.join(df2)
print (df4)
   a  b    c     d
a  0  5  0.0  10.0
b  1  3  1.0  20.0
c  2  6  NaN   NaN
d  3  9  NaN   NaN
e  4  2  NaN   NaN
f  5  4  NaN   NaN

#default outer join
df5 = pd.concat([df1, df2], axis=1)
print (df5)
     a    b    c     d
a  0.0  5.0  0.0  10.0
b  1.0  3.0  1.0  20.0
c  2.0  6.0  NaN   NaN
d  3.0  9.0  NaN   NaN
e  4.0  2.0  NaN   NaN
f  5.0  4.0  NaN   NaN
h  NaN  NaN  2.0  30.0
i  NaN  NaN  3.0  40.0
jezrael
fonte
2
legais. para os outros a ler isto, se ele não está funcionando, veja se você precisa para .transpose()um de seus dfs para sincronizar os índices - que foi meu problema
Jona
2
Muito obrigado. Ótima resposta. Mas por que concattem que colocar df entre parênteses enquanto joine mergenão?
Bowen Liu
@Bowen Liu Na minha opinião para possíveis DataFrames concat múltiplas em lista como dfs = [df1, df2, df3,... dfn]e, em seguidadf = pd. concat(dfs)
Jezrael
@jezrael Você poderia verificar minha nova pergunta em stackoverflow.com/questions/57133848/…
Msquare
29

você pode usar concat ([df1, df2, ...], axis = 1) para concatenar dois ou mais DFs alinhados por índices:

pd.concat([df1, df2, df3, ...], axis=1)

ou mesclar para concatenar por campos / índices personalizados:

# join by _common_ columns: `col1`, `col3`
pd.merge(df1, df2, on=['col1','col3'])

# join by: `df1.col1 == df2.index`
pd.merge(df1, df2, left_on='col1' right_index=True)

ou junte - se para participar por índice:

 df1.join(df2)
MaxU
fonte
6

Por padrão:
joinuma junção esquerda em
pd.mergecolunas
pd.concaté uma junção interna em colunas é uma junção externa em colunas

pd.concat:
aceita argumentos iteráveis. Portanto, ele não pode receber DataFrames diretamente (use [df,df2]) As
dimensões do DataFrame devem corresponder ao longo do eixo

Joine pd.merge:
pode receber argumentos do DataFrame

vicpal
fonte
5

Um bug bobo que me pegou: as junções falharam porque o índice era dtypesdiferente. Isso não era óbvio, pois as duas tabelas eram tabelas dinâmicas da mesma tabela original. Depois reset_index, os índices pareciam idênticos em Jupyter. Ele só veio à tona ao salvar no Excel ...

Corrigido com: df1[['key']] = df1[['key']].apply(pd.to_numeric)

Espero que isso economize alguém por uma hora!

Stephen Morrell
fonte
4

Se você deseja juntar dois quadros de dados no pandas, você pode simplesmente usar os atributos disponíveis, como mergeou concatenate. Por exemplo, se eu tiver dois quadros de dados df1e df2puder me juntar a eles:

newdataframe=merge(df1,df2,left_index=True,right_index=True)
vignesh babu
fonte