更新熊猫行,没有麻烦

时间:2018-10-10 23:16:21

标签: python pandas loops

我有一个本地数据框,每天都会附加新的条目。偶尔会更新旧条目。赠送的内容是一堆将匹配的列,但是时间戳是最近的。

为了删除旧条目并保留新的(更新的)条目,我附加了新条目,然后通过遍历行并查找旧条目来“清理”数据框:

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 :(得分:1)

这可以通过在groupby上使用crit1并选择最新行来完成,例如:

df.sort_values('date').groupby('crit1').tail(1)

答案 1 :(得分:1)

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

答案 2 :(得分:0)

新条目的日期可能早于已存在的日期。那么仅仅先进行掺杂或后进行掺杂可能是不正确的。

另一种选择是通过查找最小条目来删除重复项。

下面是一个可行的示例。

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