我有一个本地数据帧,每天都会追加新的条目。每隔一段时间,就会更新一个旧条目。结果是一堆列将匹配,但时间戳是最近的。
为了删除旧的条目,并保留新的(更新的)条目,我附加了新的条目,然后通过循环遍历各行并找到旧的条目来“清理”数据帧:
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
,也想不出一种在给定不同数据类型的情况下使用向量化的方法。
发布于 2018-10-11 07:48:40
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
发布于 2018-10-11 07:19:48
这可以使用crit1
上的groupby
并选择最新的行来完成,如下所示:
df.sort_values('date').groupby('crit1').tail(1)
发布于 2018-10-11 08:35:13
可能新条目的日期早于已存在的条目。那么仅仅通过第一次或最后一次掺杂可能是不正确的。
另一种选择是通过查找最小条目来删除副本。
下面是一个设计好的例子。
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()]
https://stackoverflow.com/questions/52750025
复制相似问题