识别 Pandas Dataframe 中一组参数的变化并创建一个增量值
Identify a change in a group of parameters within Pandas Dataframe and create an incrementing value
我有一个数据框:
dct = {'A':['abc','abc','abc', 'xyz', 'xyz','abc','abc','abc', 'xyz', 'xyz', 'xyz', 'xyz'],
'B':['a','a','a','a','a','z','z','z','p','p','p','q'],
'C':[1,1,1,1,2,5,5,5,9,9,9,9],
'GROUP':[123,123,123,123,123,456,456,456,767,767,767,767]
}
df = pd.DataFrame(dct)
A B C GROUP
0 abc a 1 123
1 abc a 1 123
2 abc a 1 123
3 xyz a 1 123
4 xyz a 2 123
5 abc z 5 456
6 abc z 5 456
7 abc z 5 456
8 xyz p 9 767
9 xyz p 9 767
10 xyz p 9 767
11 xyz q 9 767
我正在尝试创建一个名为 'change' 的新列。
假设我按组分组,并且当 A、B 或 C 列中的任何内容与上一行发生变化时发生变化。 'change' 该组增加 1。如果没有任何变化,则保持相同的值。当一个新组开始时,更改值再次从 1 开始。我可以使用列表和循环来完成此操作,但感觉应该使用 pandas?
示例输出如下所示:
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
5 abc z 5 456 1
6 abc z 5 456 1
7 abc z 5 456 1
8 xyz p 9 767 1
9 xyz p 9 767 1
10 xyz p 9 767 1
11 xyz q 9 767 2
您可以使用双 groupby
和 groupby 编号 (ngroup
):
df['change'] = (df.groupby('GROUP', group_keys=False)
.apply(lambda d: d.groupby(list(df.columns), sort=False)
.ngroup().add(1))
)
输出:
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
5 abc z 5 456 1
6 abc z 5 456 1
7 abc z 5 456 1
8 xyz p 9 767 1
9 xyz p 9 767 1
10 xyz p 9 767 1
11 xyz q 9 767 2
您可以计算每组 non-duplicated 个值的累计和:
df["change"] = (df.groupby("GROUP", group_keys=False)
.apply(lambda gr: (~gr.duplicated()).cumsum()))
获得
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
5 abc z 5 456 1
6 abc z 5 456 1
7 abc z 5 456 1
8 xyz p 9 767 1
9 xyz p 9 767 1
10 xyz p 9 767 1
11 xyz q 9 767 2
group_keys=False
不会在 apply
之后产生 MultiIndex 并通过索引对齐简化赋值。
一个示例组及其作用:
>>> gr = df.groupby("GROUP", group_keys=False).get_group(123)
>>> gr
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
# note the `~` in front; negates the result
# so the "first" seen values are True
>>> ~gr.duplicated()
0 True
1 False
2 False
3 True
4 True
dtype: bool
>>> (~gr.duplicated()).cumsum()
0 1
1 1
2 1
3 2
4 3
dtype: int32
因此,对于重复的标记,错误的标记(即重复项)不会对累积和有贡献,并且会通过它们保持不变。
我有一个数据框:
dct = {'A':['abc','abc','abc', 'xyz', 'xyz','abc','abc','abc', 'xyz', 'xyz', 'xyz', 'xyz'],
'B':['a','a','a','a','a','z','z','z','p','p','p','q'],
'C':[1,1,1,1,2,5,5,5,9,9,9,9],
'GROUP':[123,123,123,123,123,456,456,456,767,767,767,767]
}
df = pd.DataFrame(dct)
A B C GROUP
0 abc a 1 123
1 abc a 1 123
2 abc a 1 123
3 xyz a 1 123
4 xyz a 2 123
5 abc z 5 456
6 abc z 5 456
7 abc z 5 456
8 xyz p 9 767
9 xyz p 9 767
10 xyz p 9 767
11 xyz q 9 767
我正在尝试创建一个名为 'change' 的新列。
假设我按组分组,并且当 A、B 或 C 列中的任何内容与上一行发生变化时发生变化。 'change' 该组增加 1。如果没有任何变化,则保持相同的值。当一个新组开始时,更改值再次从 1 开始。我可以使用列表和循环来完成此操作,但感觉应该使用 pandas?
示例输出如下所示:
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
5 abc z 5 456 1
6 abc z 5 456 1
7 abc z 5 456 1
8 xyz p 9 767 1
9 xyz p 9 767 1
10 xyz p 9 767 1
11 xyz q 9 767 2
您可以使用双 groupby
和 groupby 编号 (ngroup
):
df['change'] = (df.groupby('GROUP', group_keys=False)
.apply(lambda d: d.groupby(list(df.columns), sort=False)
.ngroup().add(1))
)
输出:
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
5 abc z 5 456 1
6 abc z 5 456 1
7 abc z 5 456 1
8 xyz p 9 767 1
9 xyz p 9 767 1
10 xyz p 9 767 1
11 xyz q 9 767 2
您可以计算每组 non-duplicated 个值的累计和:
df["change"] = (df.groupby("GROUP", group_keys=False)
.apply(lambda gr: (~gr.duplicated()).cumsum()))
获得
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
5 abc z 5 456 1
6 abc z 5 456 1
7 abc z 5 456 1
8 xyz p 9 767 1
9 xyz p 9 767 1
10 xyz p 9 767 1
11 xyz q 9 767 2
group_keys=False
不会在 apply
之后产生 MultiIndex 并通过索引对齐简化赋值。
一个示例组及其作用:
>>> gr = df.groupby("GROUP", group_keys=False).get_group(123)
>>> gr
A B C GROUP change
0 abc a 1 123 1
1 abc a 1 123 1
2 abc a 1 123 1
3 xyz a 1 123 2
4 xyz a 2 123 3
# note the `~` in front; negates the result
# so the "first" seen values are True
>>> ~gr.duplicated()
0 True
1 False
2 False
3 True
4 True
dtype: bool
>>> (~gr.duplicated()).cumsum()
0 1
1 1
2 1
3 2
4 3
dtype: int32
因此,对于重复的标记,错误的标记(即重复项)不会对累积和有贡献,并且会通过它们保持不变。