Обновление строки Pandas без iterrows - PullRequest
0 голосов
/ 11 октября 2018

У меня есть локальный фрейм данных, к которому ежедневно добавляются новые записи.Время от времени старая запись обновляется.Выдача - это набор столбцов, но отметка времени более поздняя.

С целью удаления старой записи и сохранения новой (обновленной) записи я добавляю новую запись, а затем "очищаю" кадр данных, просматривая строки и находя старую запись:

del_rows=[]
df2 = df.copy()
for index, row in df.iterrows():
    for index2, row2 in df2.iterrows():
        if row["crit1"]==row2["crit1"] and row["date"] > row2["date"]:
            del_rows.append(index2)

df = df.drop(df.index[del_rows])

Будучи функциональным, я бы хотел узнать более "панд" способ этого процесса.Я знаю, что apply и векторизация NumPy быстрее;однако я не могу придумать функцию, которая могла бы достичь этого, которую я мог бы отобразить apply, или способ использования векторизации для различных типов данных.

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

IIUC, вы можете использовать duplicated() для создания логического фильтра, поэтому для образца кадра данных:

    crit1        date
0   test1  01-01-2018
1   test2  01-02-2018
2   test3  01-03-2018
3   test4  01-04-2018
4   test5  01-05-2018
5   test6  01-06-2018
6   test3  01-07-2018
7   test7  01-08-2018
8   test8  01-09-2018
9   test2  01-10-2018
10  test9  01-11-2018

Просто выполните:

df[~df.duplicated(subset=['crit1'], keep='last')].reset_index(drop=True)

Выход:

   crit1        date
0  test1  01-01-2018
1  test4  01-04-2018
2  test5  01-05-2018
3  test6  01-06-2018
4  test3  01-07-2018
5  test7  01-08-2018
6  test8  01-09-2018
7  test2  01-10-2018
8  test9  01-11-2018
0 голосов
/ 11 октября 2018

Возможно, новая запись имеет дату старше, чем уже существующая.тогда допинг просто первым или последним может быть неправильным.

другой альтернативой является удаление дубликата путем нахождения минимальной записи.

ниже приведенный пример.

import pandas as pd

date = pd.date_range(start='1/1/2018', end='1/5/2018')

crit = ['a', 'b', 'c', 'd', 'e']

df = pd.DataFrame({'crit':crit, 'date':date})

# insert a new entry to df
df.loc[len(df)] = ['b', '1/6/2016']

#convert date to datetime
df['date'] = pd.to_datetime(df['date'])

print(df, '\n')


#find the duplicated row in crit

print(df[df.duplicated('crit', keep=False)]['date'].min(), '\n')
print(df['date'] != df[df.duplicated('crit', keep=False)]['date'].min())

#apply 
df[df['date'] != df[df.duplicated('crit', keep=False)]['date'].min()]

enter image description here

0 голосов
/ 11 октября 2018

Это можно сделать, используя groupby на crit1 и выбрав самую последнюю строку, например:

df.sort_values('date').groupby('crit1').tail(1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...