pandas 基于groupby导出一个bool列,并将当前行与前一行进行比较

cu6pst1q  于 2023-10-14  发布在  其他
关注(0)|答案(2)|浏览(164)

我试图计算几个组的行号,只有当当前行的分类值与以前的。
我在考虑计算每个组的布尔级数,然后调用cumsum(),这将给予我所需要的(尽管我毫不怀疑可能有更好的方法)。
我的测试数据集看起来像:

  1. df = pd.DataFrame({
  2. "id_1": [1, 1, 1, 2, 2, 2, 2, 2, 2],
  3. "id_2": ["a", "a", "a", "a", "a", "a", "b", "b", "b"],
  4. "class_1": [1, 1, 1, 1, 1, 1, 2, 1, 2],
  5. "class_2": [1, 1, 2, 1, 2, 2, 2, 1, 2]
  6. })

| id_1| id_2| class_1|二级|
| --|--|--|--|
| 1 |一| 1 | 1 |
| 1 |一| 1 | 1 |
| 1 |一| 1 | 2 |
| 2 |一| 1 | 1 |
| 2 |一| 1 | 2 |
| 2 |一| 1 | 2 |
| 2 |B| 2 | 2 |
| 2 |B| 1 | 1 |
| 2 |B| 2 | 2 |
我想对id列进行分组并比较classification列。
到目前为止,我有:

  1. df["t_id"] = df.groupby(['id_1', 'id_2'], as_index=False)['class_1'].apply(lambda x: (x != x.shift()).cumsum())
  2. df

这将产生如下所示的正确输出:
| id_1| id_2| class_1|二级|t_id|
| --|--|--|--|--|
| 1 |一| 1 | 1 | 1 |
| 1 |一| 1 | 1 | 1 |
| 1 |一| 1 | 2 | 1 |
| 2 |一| 1 | 1 | 1 |
| 2 |一| 1 | 2 | 1 |
| 2 |一| 1 | 2 | 1 |
| 2 |B| 2 | 2 | 1 |
| 2 |B| 1 | 1 | 2 |
| 2 |B| 2 | 2 | 3 |
但是,这只会将class_1列中的每个值与前一行的值进行比较。我无法理解如何将class_2作为比较的一部分。我希望它会像下面这样,但唉,这不工作!

  1. df["t_id"] = df.groupby(["id_1", "id_2"], as_index=False)["class_1", "class_2"].apply(lambda x: ((x["class_1"] != x["class_2"].shift()) or (x["class_2"] != x["class_2"].shift())).cumsum())
  2. df

下面是我在考虑class_class_2列时所期望的结果:
| id_1| id_2| class_1|二级|t_id|
| --|--|--|--|--|
| 1 |一| 1 | 1 | 1 |
| 1 |一| 1 | 1 | 1 |
| 1 |一| 1 | 2 | 2 |
| 2 |一| 1 | 1 | 1 |
| 2 |一| 1 | 2 | 2 |
| 2 |一| 1 | 2 | 2 |
| 2 |B| 2 | 2 | 1 |
| 2 |B| 1 | 1 | 2 |
| 2 |B| 2 | 2 | 3 |
我使用Python 1.8和Pandas 1.5.3(尽管我可能需要针对Pandas 0.22.1)。
建议欢迎。先谢了。

g6baxovj

g6baxovj1#

我相信有几种方法可以做到这一点,但要修复您采用的方法,而不是x["class_2"].shift(),您需要执行x.shift()["class_2"]

  1. df['t_id'] = df.groupby(['id_1', 'id_2'], as_index=False).apply(lambda x: ((x['class_1'] != x.shift()['class_1']) | (x['class_2'] != x.shift()['class_2'])).cumsum()).reset_index()[0]
  2. print(df)

输出量:

  1. id_1 id_2 class_1 class_2 t_id
  2. 0 1 a 1 1 1
  3. 1 1 a 1 1 1
  4. 2 1 a 1 2 2
  5. 3 2 a 1 1 1
  6. 4 2 a 1 2 2
  7. 5 2 a 1 2 2
  8. 6 2 b 2 2 1
  9. 7 2 b 1 1 2
  10. 8 2 b 2 2 3
jk9hmnmh

jk9hmnmh2#

另一个解决方案:比较由多个列组成的元组:

  1. def fn(x):
  2. t = x[["class_1", "class_2"]].apply(tuple, axis=1)
  3. return (t != t.shift()).cumsum()
  4. df["t_id"] = df.groupby(["id_1", "id_2"], group_keys=False).apply(fn)
  5. print(df)

图纸:

  1. id_1 id_2 class_1 class_2 t_id
  2. 0 1 a 1 1 1
  3. 1 1 a 1 1 1
  4. 2 1 a 1 2 2
  5. 3 2 a 1 1 1
  6. 4 2 a 1 2 2
  7. 5 2 a 1 2 2
  8. 6 2 b 2 2 1
  9. 7 2 b 1 1 2
  10. 8 2 b 2 2 3
展开查看全部

相关问题