Слияние Pandas Dataframe в столбце со структурированными данными

Сценарий. В продолжение предыдущего вопроса о том, как прочитать файл Excel из подачи в фрейм данных (Как читать файл Excel непосредственно с сервера с Python), я пытаюсь объединить контексты нескольких фреймов данных ( которые содержат данные из листов Excel).

Проблема: даже после поиска похожих проблем здесь, в SO, я все еще не смог решить проблему.

Формат данных (каждый лист считывается во фрейм данных):

Sheet 1 (db1)
Name       CUSIP       Date       Price

 A          XXX     01/01/2001     100
 B          AAA     02/05/2005      90
 C          ZZZ     03/07/2006      95

Sheet2 (db2)
Ident      CUSIP       Value      Class

 123        XXX          0.5        AA
 444        AAA          1.3        AB
 555        ZZZ          2,8        AC

Требуемый вывод (fnl):

Name       CUSIP       Date       Price       Ident       Value      Class
 A          XXX     01/01/2001     100         123          0.5        AA
 B          AAA     02/05/2005      90         444          1.3        AB
 C          ZZZ     03/07/2006      95         555          2.8        AC

Что я уже пробовал: я пытаюсь использовать функцию слияния для сопоставления каждого фрейма данных, но получаю сообщение об ошибке в части "как".

fnl = db1

fnl = fnl.merge(db2, how='outer', on=['CUSIP'])

fnl = fnl.merge(db3, how='outer', on=['CUSIP'])

fnl = fnl.merge(bte, how='outer', on=['CUSIP'])

Я также пробовал объединить, но я просто получил список фреймов данных вместо одного вывода.

wsframes = [db1 ,db2, db3]

fnl = pd.concat(wsframes, axis=1)

Вопрос: Как правильно выполнять эту операцию?


person DGMS89    schedule 18.08.2017    source источник
comment
какую ошибку вы получаете?   -  person omu_negru    schedule 18.08.2017
comment
KeyError: «CUSIP» для процедуры слияния. Для concat я получаю список фреймов данных, но я не могу собрать их вместе для выполнения операций.   -  person DGMS89    schedule 18.08.2017
comment
Ваша ошибка предполагает, что «CUSIP» не отображается в виде столбца. Что вы получаете, когда пишете db1['CUSIP'] или db2['CUSIP']?   -  person omu_negru    schedule 18.08.2017
comment
Фактически та же ошибка. Может ли это быть из-за того, что данные отделяются от заголовков одной пустой строкой?   -  person DGMS89    schedule 18.08.2017
comment
как насчет db2.columns.tolist() и db2.index.tolist()   -  person omu_negru    schedule 18.08.2017
comment
Они отображаются как Безымянный, я думаю, проблема в пустой строке.   -  person DGMS89    schedule 18.08.2017
comment
да. Проблема заключалась в лишнем ряду. Я удалил и теперь работает. Спасибо за помощь.   -  person DGMS89    schedule 18.08.2017


Ответы (1)


Кажется, вам нужно:

from functools import reduce
#many dataframes
dfs = [df1,df2]
df = reduce(lambda x, y: x.merge(y, on='CUSIP', how='outer'), dfs)
print (df)
  Name CUSIP        Date  Price  Ident Value Class
0    A   XXX  01/01/2001    100    123   0.5    AA
1    B   AAA  02/05/2005     90    444   1.3    AB
2    C   ZZZ  03/07/2006     95    555   2,8    AC

Но столбцы в каждом фрейме данных должны быть разными (нет совпадающих столбцов (здесь CUSIP)), иначе получаются суффиксы _x и _y:

dfs = [df1,df1, df2]
df = reduce(lambda x, y: x.merge(y, on='CUSIP', how='outer'), dfs)
print (df)
  Name_x CUSIP      Date_x  Price_x Name_y      Date_y  Price_y  Ident Value  \
0      A   XXX  01/01/2001      100      A  01/01/2001      100    123   0.5   
1      B   AAA  02/05/2005       90      B  02/05/2005       90    444   1.3   
2      C   ZZZ  03/07/2006       95      C  03/07/2006       95    555   2,8   

  Class  
0    AA  
1    AB  
2    AC  
person jezrael    schedule 18.08.2017
comment
Я думаю, он уже пробовал объединить, но жаловался на ошибку - person omu_negru; 18.08.2017
comment
Я не думаю, что необходимо использовать другую библиотеку, например, functools. Он также мог установить_index на CUSIP и выполнить слияние. - person Wli; 18.08.2017
comment
@Wli - да, но если нужно объединить множество фреймов данных, это проще. - person jezrael; 18.08.2017
comment
Хороший ответ ~~! - person BENY; 18.08.2017