我有一个如下所示的数据框(z):
timestamp source price
2004-01-05 14:55:09+00:00 Bank1 420.975
2004-01-05 14:55:10+00:00 Bank2 421.0
2004-01-05 14:55:22+00:00 Bank1 421.075
2004-01-05 14:55:34+00:00 Bank1 420.975
2004-01-05 14:55:39+00:00 Bank1 421.175
2004-01-05 14:55:45+00:00 Bank1 421.075
2004-01-05 14:55:52+00:00 Bank1 421.175
2004-01-05 14:56:12+00:00 Bank2 421.1
2004-01-05 14:56:33+00:00 Bank1 421.275
有时,银行2只提交1个报价的时间窗口 - 我需要抛弃这样的所有日子,因为银行需要2个或更多报价。如果Bank 2出现1次或更少次,那就扔掉那一天。
我通过创建一个布尔掩码来完成此操作,我计划从中筛选出符合条件的所有日子:
r = z.groupby([z.index.date, z['source']]).size() > 1
# return boolean for each day/source if it appears at least once
r = r.groupby(level=0).all() == True
# ie. if the datetime 0th-level index contains all True, return True, otherwise False (meaning one source failed the criteria)
这会产生:
2004-01-05 True
2004-01-06 True
2004-01-07 True
2004-01-08 False
2004-01-09 True
完美。现在我只需要从原始数据帧z
中过滤它,同时保持原始结构(即第二级频率,而不是每天)。这意味着使用df.filter()方法。
我的原始数据框架具有相同的结构(并且它们的.shape [0]相同):
2004-01-05 94
2004-01-06 24
2004-01-07 62
2004-01-08 30
2004-01-09 36
大
这里我感到困惑。我跑:
t = y.groupby(y.index.date).filter(lambda x: [x for x in r])
接收TypeError: filter function returned a list, but expected a scalar bool
。
lambda
函数只返回r
中的每个x(布尔值)。我在一个非常复杂的情况下解决了这个问题(只是把我之前解决的所有事情都解决了,并且不要把它扔进r
变量,而是让它成为lambda
函数的一部分)。
t = y.groupby(y.index.date).filter(lambda x: (x.groupby([x.index.date, x['source']]).size() > 1).groupby(level=0).all() == True) # ie. the datetime 0th-level index
这非常凌乱,必须有一个基本的说法,这里是我的数据框z
,然后是groupby('z.index.date')
,然后基于布尔掩码.filter()
r
编辑:这是我从大熊猫教程中找到的,但我出于某种原因,.between_time()部分不起作用。它会过滤掉长度为< = 1的所有内容,而不仅仅是当.between_time()条件为真时。
t = y.groupby([y.index.date, y['source']]).filter(lambda x: len(x.between_time('14:00','15:00') > 1)
答案 0 :(得分:0)
您建议的原始方法是正确的,但您必须在群组上使用transform
(date
和source
)而不是apply
。 transform
使用与原始数据框相同的结构返回组信息。
grp = z.groupby([z.index.date,z.source])
counts = grp.transform('count') #counts the records for each group and index the information with the same structure of z
filtered_z = z[counts > 1] #final filtering
答案 1 :(得分:0)
我想我想出了这个日期:
仅在数据框z
z['date'] = z.index.date
然后保留布尔系列r
z[z['date'].isin(r.index)]