Слияние двух неправильных фреймов данных в Python

У меня есть два фрейма данных df1 и df2

    ID      Range(US)            Count(US)          Mean(US)
0   690      1-3                 266                4.0
1            4-7                 277                NaN
2   354      1-3                 233                2.0
3            4-7                 85                 NaN
4   947      1-3                 156                4.0

а также

    ID   Range(UK)           Count(UK)          Mean(UK)
0   690      1-3                 186                4.0
1            4-7                 25                 NaN
2   354      1-3                 44                 1.0
3   947      1-3                 213                3.0
4            4-7                 33                 NaN

Я объединил с помощью кода:
In:df=df1.merge(df2, left_on='deviceid',right_on='deviceid', how='left') df

 ID  Range(US)   Count(US)    Mean(US)   Range(UK)  Count(UK)    Mean(UK)       
 0  690    1-3      266         4.0        1-3        186         4.0
 1         4-7      277         NaN        4-7        25          NaN
 2         4-7      277         NaN        4-7        33          NaN
 3  354    1-3      233         2.0        1-3        44          1.0
 4         4-7      85          NaN        4-7        25          NaN
 5         4-7      85          NaN        4-7        33          NaN
 6  947    1-3      156         4.0        1-3        213         3.0

Из приведенного выше мы видим, что значения повторяются снова для некоторых значений, если они отсутствуют.

Но ожидаемый результат

   ID  Range(US)   Count(US)  Mean(US)   Range(UK)  Count(UK)    Mean(UK)       
 0  690    1-3      266         4.0        1-3        186         4.0
 1         4-7      277         NaN        4-7        25          NaN
 2  354    1-3      233         2.0        1-3        44          1.0
 3         4-7      85          NaN        Nan        NaN         NaN
 4  947    1-3      156         4.0        1-3        213         3.0
 5         4-7      Nan         Nan        4-7        33          Nan

person san    schedule 05.06.2018    source источник


Ответы (1)


Сначала удалите замену duplicated ID в обоих DataFrames:

#df1['ID'] = df1['ID'].mask(df['ID'].duplicated(), '') 
#df2['ID'] = df2['ID'].mask(df['ID'].duplicated(), '') 

print (df1)
    ID Range(US)  Count(US)  Mean(US)
0  690       1-3        266       4.0
1  690       4-7        277       NaN
2  354       1-3        233       2.0
3  354       4-7         85       NaN
4  947       1-3        156       4.0

print (df2)
    ID Range(UK)  Count(UK)  Mean(UK)
0  690       1-3        186       4.0
1  690       4-7         25       NaN
2  354       1-3         44       1.0
3  947       1-3        213       3.0
4  947       4-7         33       NaN

А затем объедините оба столбца с помощью внешнего соединения:

df = df1.merge(df2, left_on=['ID', 'Range(US)'], right_on=['ID', 'Range(UK)'], how='outer')
print (df)
    ID Range(US)  Count(US)  Mean(US) Range(UK)  Count(UK)  Mean(UK)
0  690       1-3      266.0       4.0       1-3      186.0       4.0
1  690       4-7      277.0       NaN       4-7       25.0       NaN
2  354       1-3      233.0       2.0       1-3       44.0       1.0
3  354       4-7       85.0       NaN       NaN        NaN       NaN
4  947       1-3      156.0       4.0       1-3      213.0       3.0
5  947       NaN        NaN       NaN       4-7       33.0       NaN
person jezrael    schedule 05.06.2018
comment
df1 ['ID'] = df1 ['ID']. mask (df ['ID']. duplicated (), '') что здесь df? - person san; 05.06.2018
comment
@san - это опечатка, нужно #df1['ID'] = df1['ID'].mask(df1['ID'].duplicated(), '') #df2['ID'] = df2['ID'].mask(df2['ID'].duplicated(), '') - person jezrael; 05.06.2018
comment
все еще не получает ожидаемый результат - person san; 05.06.2018
comment
если поменять outer на left или inner, это поможет? - person jezrael; 05.06.2018
comment
Вы можете объяснить больше? Проблема с реальными данными? Или, если использовать данные образца данных, получить другой результат, как я в ответе? - person jezrael; 05.06.2018
comment
Я получил другой ответ на эти образцы данных - person san; 05.06.2018
comment
Ваши df1 и df2 как в ответе? ID столбец заполнен повторяющимися числами, их нет .. - person jezrael; 05.06.2018
comment
@san - да, и это проблема. нужны числовые значения. - person jezrael; 05.06.2018
comment
как заполнить 0 для всех значений нан? - person san; 05.06.2018
comment
Супер, используйте df = df.fillna(0) - person jezrael; 05.06.2018
comment
ValueError: значение заполнения должно быть в категориях - person san; 05.06.2018
comment
хммм, есть проблема с Range столбцами, из-за категорий. Дайте мне время для решения. - person jezrael; 05.06.2018
comment
Какая у вас версия панд? - person jezrael; 05.06.2018
comment
0.23.0 - моя версия панд - person san; 05.06.2018
comment
Я не могу смоделировать это, но решение должно быть df1['Range(US)'] = df1['Range(US)'].cat.add_categories([0]) и df2['Range(UK)'] = df2['Range(UK)'].cat.add_categories([0]) до merge - person jezrael; 05.06.2018
comment
cool работал отлично, но можем ли мы удалить дубликаты для всего фрейма данных? - person san; 05.06.2018
comment
хммм, сложный вопрос. Что нужно - решать вам. Но если нужно удалить дубликаты, решение должно помочь - person jezrael; 05.06.2018
comment
Позвольте нам продолжить это обсуждение в чате. - person san; 06.06.2018