signal = pd.DataFrame([[0, 0, 0],
[-1, -1, -1],
[1, 0, 0],
[0, 0, 0],
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[0, -1, 1],
[-1, 0, 0],
[0, 0, 0]],columns=['TKV','SWP','BWN'],index=date_index)
`
remove_duplicate(df,lookahead_days):
df = df.copy()
df.index = pd.to_datetime(df.index)
for i in range(0, signal.shape[0], lookahead_days-1):
date_range = df.index[i:i+lookahead_days]
for col in df.columns:
duplicates = df[col][date_range].duplicated(keep="first")
duplicates_index = df[col][date_range][duplicates].index
df.loc[duplicates_index, col] = 0
df.index = df.index.date
return df`
我的目标是在几天(loookahead_days)的窗口中循环遍历信号数据帧,并检查是否存在重复项,然后将重复项设置为零,仅保留第一个。
我已经使用上面的函数完成了此操作,现在的问题是,当我将它传递通过形状大约为1000X500的真实数据帧时,运行时间太长了。
我想知道是否应该有更好的方法。
答案 0 :(得分:0)
设置 :
from pandas import Timestamp
signal = pd.DataFrame({'TKV': {Timestamp('2018-01-01 00:00:00'): 0, Timestamp('2018-01-02 00:00:00'): -1, Timestamp('2018-01-03 00:00:00'): 1, Timestamp('2018-01-04 00:00:00'): 0, Timestamp('2018-01-05 00:00:00'): 1, Timestamp('2018-01-06 00:00:00'): 0, Timestamp('2018-01-07 00:00:00'): 0, Timestamp('2018-01-08 00:00:00'): 0, Timestamp('2018-01-09 00:00:00'): -1, Timestamp('2018-01-10 00:00:00'): 0}, 'SWP': {Timestamp('2018-01-01 00:00:00'): 0, Timestamp('2018-01-02 00:00:00'): -1, Timestamp('2018-01-03 00:00:00'): 0, Timestamp('2018-01-04 00:00:00'): 0, Timestamp('2018-01-05 00:00:00'): 0, Timestamp('2018-01-06 00:00:00'): 1, Timestamp('2018-01-07 00:00:00'): 0, Timestamp('2018-01-08 00:00:00'): -1, Timestamp('2018-01-09 00:00:00'): 0, Timestamp('2018-01-10 00:00:00'): 0}, 'BWN': {Timestamp('2018-01-01 00:00:00'): 0, Timestamp('2018-01-02 00:00:00'): -1, Timestamp('2018-01-03 00:00:00'): 0, Timestamp('2018-01-04 00:00:00'): 0, Timestamp('2018-01-05 00:00:00'): 0, Timestamp('2018-01-06 00:00:00'): 0, Timestamp('2018-01-07 00:00:00'): 1, Timestamp('2018-01-08 00:00:00'): 1, Timestamp('2018-01-09 00:00:00'): 0, Timestamp('2018-01-10 00:00:00'): 0}})
您可以在此处使用 drop_duplicates
,棘手的事情是您需要创建一个列,该列将从不不会在每个{{1 }}天的时间段(或您决定的任何时间分组)。假设您想删除重复项(如果它们在5天之内出现),我们需要创建一个在每个周期内都重复的列,我们可以将其用作n
的键:
drop_duplicates
这给我们提供了一个列,该列在每个5天的时间段内始终是相同的,但是在检查重复项时可以用来区分 other 列。现在,我们要做的就是根据“标志”列以及我们要检查的其他列删除重复项:
s = (signal.reset_index()
.groupby(pd.Grouper(freq='5d', key='index'))
['index'].transform('first')
)
0 2018-01-01
1 2018-01-01
2 2018-01-01
3 2018-01-01
4 2018-01-01
5 2018-01-06
6 2018-01-06
7 2018-01-06
8 2018-01-06
9 2018-01-06
Name: index, dtype: datetime64[ns]
如果您不想删除重复项,而是想简单地将其替换为signal.assign(flag=s.values).drop_duplicates(['flag', 'TKV', 'SWP', 'BWN']).drop('flag', 1)
TKV SWP BWN
2018-01-01 0 0 0
2018-01-02 -1 -1 -1
2018-01-03 1 0 0
2018-01-06 0 1 0
2018-01-07 0 0 1
2018-01-08 0 -1 1
2018-01-09 -1 0 0
2018-01-10 0 0 0
,则可以在此处使用 0
。
duplicated
这导致第一组中的最后两个条目被删除,因为它们在该时间段内重复出现,但是第二组中的 not 行即使出现在第一组中也是如此。
这应该比您选择的要好得多:
tmp = signal.assign(flag=s.values)
tmp[tmp.duplicated()] = 0
tmp = tmp.drop('flag', 1)
TKV SWP BWN
2018-01-01 0 0 0
2018-01-02 -1 -1 -1
2018-01-03 1 0 0
2018-01-04 0 0 0
2018-01-05 0 0 0
2018-01-06 0 1 0
2018-01-07 0 0 1
2018-01-08 0 -1 1
2018-01-09 -1 0 0
2018-01-10 0 0 0