我有一个DataFrame,其中包含名称,年份,标签和一堆其他变量 . 所以它可能看起来像这样
df = pd.DataFrame({
"name": 4*["A"] + 5*["B"],
"year": [1999,2000,2001,2002,2010,2011,2012,2013,2014],
"tag": [0,1,0,0,1,0,0,1,0],
"x1": np.random.normal(size=9),
"x2": np.random.uniform(size=9)
})
print df
name tag x1 x2 year
0 A 0 -1.352707 0.932559 1999
1 A 1 -1.359828 0.724635 2000
2 A 0 1.289980 0.477135 2001
3 A 0 -0.409960 0.863443 2002
4 B 1 -1.469220 0.324349 2010
5 B 0 0.372617 0.871734 2011
6 B 0 -0.047398 0.307596 2012
7 B 1 1.240108 0.667082 2013
8 B 0 0.558432 0.284363 2014
我正在寻找一种方法来将DataFrame分组或拆分成块,每个块应包含
-
一行标签== 1和
-
存在tag == 0,row [year 1]和row [year-1]的所有行,row [[year -1,"tag"]] == 1和row [[year -1,"name"]] == row [[年,"name"]] .
Simpy说,我想要大小为3的块,其中中间行被标记,并被同一公司的两个未标记的行包围 . 所以在上面的例子中,只有两个通过这些条件的块是
name tag x1 x2 year
0 A 0 -1.352707 0.932559 1999
1 A 1 -1.359828 0.724635 2000
2 A 0 1.289980 0.477135 2001
和
7 B 0 -0.047398 0.307596 2012
8 B 1 1.240108 0.667082 2013
9 B 0 0.558432 0.284363 2014
我考虑过按多列分组,但问题是我需要分组的行没有任何共同点,而是名称 . 我还考虑过手动引入(在for循环中)另一个列,它为每个块提供一个新ID,然后我可以将其分组 . 然而,我对这种方法非常不满意,因为它看起来既不高效又不优雅 .
我很欣赏任何想法 .
2 回答
尽管@ ScottBoston的答案对于我在问题中给出的DataFrame非常有用,但是在缺少一年的情况下它不起作用 . 所以例如在的情况下
代码会给
根据原始问题中的第二个条件(2008年,2010年和2011年),显示第一个块的大小是错误的,第二个块不应该在那里 .
这两个人的问题是
问题明确地保持了一行在多个块中的可能性,因此一个额外的索引通常不够 .
必须包含年份条件,因此滚动计算需要同时在两列(标签和年份)上,根据https://stackoverflow.com/a/37491779/2336654,目前pandas不支持 .
所以我现在的解决方法如下
只是想我应该添加这个,以防将来有人想知道为什么接受的答案不适用于类似的问题 .
让我们试试这一点逻辑:
其中chunks_df是您的分解数据框的字典:
细节:
使用cumsum对每个标记进行唯一标识/标记== 1 .
使用窗口为3的滚动并获取该居中窗口的最大值,以选择-1,1和1 .