pandas:如何按多个条件过滤分组数据?

8

我有一个数据框,看起来像这样:

df = pd.DataFrame([
  {'id': 123, 'date': '2016-01-01', 'is_local': True },
  {'id': 123, 'date': '2017-01-01', 'is_local': False },
  {'id': 124, 'date': '2016-01-01', 'is_local': True },
  {'id': 124, 'date': '2017-01-01', 'is_local': True }
])
df.date = df.date.astype('datetime64[ns]')

我希望获得一个列表,其中包含在2016年初为True但在2017年初为False的所有ID。 我已经通过ID进行了分组:

gp = df.groupby('id')

我尝试了根据第二个条件进行过滤(作为开始的方式),但它返回了所有的组:

gp.apply(lambda x: ~x.is_local & (x.date > '2016-12-31'))

我该如何按照需要进行筛选?
3个回答

8
d1 = df.set_index(['id', 'date']).is_local.unstack()
d1.index[d1['2016-01-01'] & ~d1['2017-01-01']].tolist()

[123]

3
通过 数据透视表 的方式,也可以完成这项操作:
In [24]: ids_by_dates = df.pivot(index='id', columns='date',values='is_local')

In [25]: ids_by_dates['2016-01-01'] & ~ids_by_dates['2017-01-01']
Out[25]: 
id
123     True
124    False

3
你可以尝试使用datetime库中的datetime模块,并为数据框传递多个条件。
from datetime import datetime
df = pd.DataFrame([
  {'id': 123, 'date': '2016-01-01', 'is_local': True },
  {'id': 123, 'date': '2017-01-01', 'is_local': False },
  {'id': 124, 'date': '2016-01-01', 'is_local': True },
  {'id': 124, 'date': '2017-01-01', 'is_local': True }
])
df.date = df.date.astype('datetime64[ns]')

使用多个条件来切割所需的数据框

a = df[(df.is_local==True) & (df.date<datetime(2016,12,31) & (df.date>datetime(2015,12,31))]
b = df[(df.is_local==False) & (df.date<datetime(2017,12,31)) & (df.date>datetime(2016,12,31))]

后续使用pandas连接数据

final_df = pd.concat((a,b))

将输出第1行和第2行

    date        id  is_local
2   2016-01-01  124 True
1   2017-01-01  123 False

在单行中,如下所示
final_df = pd.concat((df[(df.is_local==True) & (df.date<datetime(2016,12,31) & (df.date>datetime(2015,12,31))], df[(df.is_local==False) & (df.date<datetime(2017,12,31)) & (df.date>datetime(2016,12,31))]))

谢谢 - 我该如何使用这个来获取所有在2016年初has_local为True且在2017年为False的行? - Richard
我只能想到一个不太好的解决方案,即添加多个条件并将它们连接在一起。我已相应地编辑了我的答案。 - Raja Sattiraju
我还编辑了我的答案,加入了另一个条件,将年份限制在2016年和2017年。 - Raja Sattiraju

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接