pandas: 按多个条件过滤分组?
pandas: filter group by multiple conditions?
我有一个如下所示的数据框:
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]')
我想获取所有 ID 的列表,其中 is_local
在 2016 年初为 True,但在 2017 年初为 False。我首先按 ID 分组:
gp = df.groupby('id')
然后我试过这只是为了按这些条件中的第二个进行过滤(作为一种入门方式),但它返回了所有组:
gp.apply(lambda x: ~x.is_local & (x.date > '2016-12-31'))
如何按照我需要的方式进行过滤?
d1 = df.set_index(['id', 'date']).is_local.unstack()
d1.index[d1['2016-01-01'] & ~d1['2017-01-01']].tolist()
[123]
另一种方法是通过 pivoting:
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
您可以尝试使用 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))]))
我有一个如下所示的数据框:
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]')
我想获取所有 ID 的列表,其中 is_local
在 2016 年初为 True,但在 2017 年初为 False。我首先按 ID 分组:
gp = df.groupby('id')
然后我试过这只是为了按这些条件中的第二个进行过滤(作为一种入门方式),但它返回了所有组:
gp.apply(lambda x: ~x.is_local & (x.date > '2016-12-31'))
如何按照我需要的方式进行过滤?
d1 = df.set_index(['id', 'date']).is_local.unstack()
d1.index[d1['2016-01-01'] & ~d1['2017-01-01']].tolist()
[123]
另一种方法是通过 pivoting:
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
您可以尝试使用 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))]))