Я собираю в Интернете некоторые данные (автоматизированные для выполнения почасовой задачи) и хочу, чтобы вновь собранные данные были добавлены к фрейму данных, с которого я начал, так, чтобы фрейм данных (далее: df_total
) продолжал получатьбольше.
Каждый раз, когда данные очищаются, они получают временную метку, но я не хочу перезаписывать временную метку при повторной очистке того же самого элемента данных (может быть идентифицирован по уникальным идентификаторам).
Кроме того, записи могут быть отмеченыкак active или неактивно , и если ранее active запись превращает неактивно в более позднюю очистку, это следует очистить в данных, добавивновая отметка времени, показывающая, когда предложение неактивно.
У меня есть следующие данные (df_total
, df_new
), которые я хотел бы объединить и обновить:
# df_total:
ID Names Timestamp Active Inactive-Stamp
0 121 A 20190626-120000 True
1 122 B 20190626-120000 True
2 123 C 20190626-120000 True
# df_new:
ID Names Timestamp Active Inactive-Stamp
0 122 B 20190627-140000 True
1 123 C 20190627-140000 False
2 124 D 20190627-140000 True
Что работает:
Само слияние и обновление работает благодаря следующему подходу:
def join_data(df_total, df_new):
# Doing a full outer join
df = df_total.merge(df_new, on=list(df_total), how='outer')
# Drop real duplicates (e.g. ID:122, Name:B)
df = df.drop_duplicates(subset=['ID', 'Active'], keep='first')
# "Add" the timestamp for the now inactive entry
df.loc[(df.duplicated(subset=['ID'],
keep='last') == True), 'Inactive-Stamp'] = "newTimeStamp"
# Change `active` (from `True` to `False`)
df.loc[(df.duplicated(subset=['ID'],
keep='last') == True), 'Active'] = False
# Delete the new duplicate
df = df[(df.duplicated(subset=['ID'],
keep='first') == False)]
# Reset index of new Dataframe
df.reset_index(inplace=True, drop=True)
return(df)
df_total = join_data(df_total, df_new)
Это приводит к объединению фреймов данных и обновлению записей, как запланировано:
ID Names Timestamp Active Inactive-Stamp
0 121 A 20190626-120000 True
1 122 B 20190626-120000 True
2 123 C 20190626-120000 False newTimeStamp
3 124 D 20190627-140000 True
Что такоеПроблема:
Снова можно изменить записи на active = True
.
Проблема в том, что некоторые пользователи деактивируют только свою запись, чтобы затем снова активировать ее (чтобы они снова отображались)в верхней части веб-сайта).
Таким образом, представленный выше метод должен снова работать с неактивными данными.Рассмотрим следующие (еще более новые) данные:
# df_newer:
ID Names Timestamp Active Inactive-Stamp
0 123 C 20190628-160000 True
1 125 E 20190628-160000 True
Что я пробовал:
Я попытался изменить метод, добавив (для timestamp
и active
):
# Changing the Inactive-Stamp:
df.loc[(df.duplicated(subset=['ID'], keep='last') == True)
&
(df['Active'][df.duplicated(subset=['ID'], keep='last')==True] == True),
'Inactive-Stamp'] = "Timestamp"
df.loc[(df.duplicated(subset=['ID'], keep='last') == True)
&
(df['Active'][df.duplicated(subset=['ID'], keep='last') =True] == False),
'Inactive-Stamp'] = ""
# Changing the Active-Boolean
df.loc[(df.duplicated(subset=['ID'], keep='last')==True)
&
(df['Active'][df.duplicated(subset=['ID'], keep='last')==True]==True),
'Active'] = False
df.loc[(df.duplicated(subset=['ID'], keep='last')==True)
&
(df['Active'][df.duplicated(subset=['ID'], keep='last')==True]==False),
'Active'] = True
Я надеялся, что это создаст Inactive-Stamp
только когда предложение было изменено на неактивно и удалит / заменит Inactive-Stamp
только тогда, когда наоборот.
Очевидно, что это немедленно меняет каждый активный , который изменяется на неактивный обратно на активный .
Вот почему я подумал сделать эти представленные утверждения вif
-условие, которое выглядит примерно так (псевдокод):
if (duplicate ID with different active & new entry is inactive):
df['Active'] = False
df['Inactive-Stamp'] = newTimeStamp
elif (duplicate ID with different active & new entry is active):
df['Active'] = True
df['Inactive-Stamp'] = ''
Но я также не знаю, как реализовать это if
-условие в DataFrame pandas и комбинации df.loc
-функции, ниявляется ли это хорошей практикой вообще.