Почему pandas выбрасывает «перекрытия данных». когда я использую pd.update?

#python #pandas

#python #pandas

Вопрос:

У меня есть мой основной фрейм данных, df_main , который имеет такую форму:

 df_main = pd.DataFrame({
    'GroupID': ([1]*7)   ([2]*2)   ([3]*6),
    'GroupName': (['String 1']*7)   (['String 2']*2)   (['String 3']*6),
    'FirstName': (['Matthew']*7)   (['Mark']*2)   (['Luke']*6),
    'LastName': (['Smith']*7)   (['Jones']*2)   (['Roberts']*6),
    'StartDate': (['2020-01-01']*7)   (['1998-01-01']*2)   (['N/A']*6),
}).replace('N/A',np.NaN)
 

df_main

У меня есть вторичный фрейм данных, df_update , который я хочу использовать для обновления основного фрейма данных. В этом фрейме данных отсутствует начальная дата для Люка Робертса:

 df_update = pd.DataFrame({
    'GroupID': [1, 2, 3],
    'GroupName': ['String 1', 'String 2', 'String 3'],
    'FirstName': ['Matthew', 'Mark', 'Luke'],
    'LastName': ['Smith', 'Jones', 'Roberts'],
    'StartDate': ['2020-01-01', '1998-01-01', '2005-01-01'],
})
 

df_update

Я установил одинаковые индексы для обоих фреймов данных:

 df_main = df_main.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df_update = df_update.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
 

df_main с MultiIndex
df_update с помощью MultiIndex

Я пытаюсь обновить df_main:

 df_main.update(df_update, overwrite=False, errors='raise')
 

Но это не работает:

 ValueError: Data overlaps.
 

Почему это так, и как я могу элегантно завершить это обновление?

РЕДАКТИРОВАТЬ: это Python 3.6.7 и Pandas 0.25.0.

Ответ №1:

Для меня, работающего над вашим решением в pandas 1.1.3 :

 df_main.update(df_update)
print (df_main)
                                       StartDate
GroupID GroupName FirstName LastName            
1       String 1  Matthew   Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
2       String 2  Mark      Jones     1998-01-01
                            Jones     1998-01-01
3       String 3  Luke      Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
 

Если нужно заменить только отсутствующие значения, используйте DataFrame.fillna :

 df_main = df_main.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df_update = df_update.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df = df_main.fillna(df_update)
print (df)
                                       StartDate
GroupID GroupName FirstName LastName            
1       String 1  Matthew   Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
2       String 2  Mark      Jones     1998-01-01
                            Jones     1998-01-01
3       String 3  Luke      Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
                            Roberts   2005-01-01
 

Если изменить данные, возможно ли увидеть разницу в решениях:

 df_update = pd.DataFrame({
    'GroupID': [1, 2, 3],
    'GroupName': ['String 1', 'String 2', 'String 3'],
    'FirstName': ['Matthew', 'Mark', 'Luke'],
    'LastName': ['Smith', 'Jones', 'Roberts'],
    'StartDate': ['1990-01-01', '1991-01-01', '1992-01-01'],
})

df_main = df_main.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df_update = df_update.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df_main.update(df_update)
print (df_main)
                                       StartDate
GroupID GroupName FirstName LastName            
1       String 1  Matthew   Smith     1990-01-01
                            Smith     1990-01-01
                            Smith     1990-01-01
                            Smith     1990-01-01
                            Smith     1990-01-01
                            Smith     1990-01-01
                            Smith     1990-01-01
2       String 2  Mark      Jones     1991-01-01
                            Jones     1991-01-01
3       String 3  Luke      Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
 

 df_main = df_main.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df_update = df_update.set_index(['GroupID', 'GroupName', 'FirstName', 'LastName'])
df = df_main.fillna(df_update)
print (df)
                                       StartDate
GroupID GroupName FirstName LastName            
1       String 1  Matthew   Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
                            Smith     2020-01-01
2       String 2  Mark      Jones     1998-01-01
                            Jones     1998-01-01
3       String 3  Luke      Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
                            Roberts   1992-01-01
 

Комментарии:

1. Похоже, это была простая проблема с обновлением. Спасибо, что поделились альтернативными подходами — очень полезно для дальнейшего использования.