提问人:Owen 提问时间:5/3/2014 最后编辑:cottontailOwen 更新时间:8/10/2023 访问量:48627
将组上的顺序计数器列添加到 pandas 数据帧
Add a sequential counter column on groups to a pandas dataframe
问:
我觉得有比这更好的方法:
import pandas as pd
df = pd.DataFrame(
columns=" index c1 c2 v1 ".split(),
data= [
[ 0, "A", "X", 3, ],
[ 1, "A", "X", 5, ],
[ 2, "A", "Y", 7, ],
[ 3, "A", "Y", 1, ],
[ 4, "B", "X", 3, ],
[ 5, "B", "X", 1, ],
[ 6, "B", "X", 3, ],
[ 7, "B", "Y", 1, ],
[ 8, "C", "X", 7, ],
[ 9, "C", "Y", 4, ],
[ 10, "C", "Y", 1, ],
[ 11, "C", "Y", 6, ],]).set_index("index", drop=True)
def callback(x):
x['seq'] = range(1, x.shape[0] + 1)
return x
df = df.groupby(['c1', 'c2']).apply(callback)
print df
为此,请执行以下操作:
c1 c2 v1 seq
0 A X 3 1
1 A X 5 2
2 A Y 7 1
3 A Y 1 2
4 B X 3 1
5 B X 1 2
6 B X 3 3
7 B Y 1 1
8 C X 7 1
9 C Y 4 1
10 C Y 1 2
11 C Y 6 3
有没有办法避免回调?
答:
125赞
Jeff
5/3/2014
#1
使用,请参阅此处的文档cumcount()
In [4]: df.groupby(['c1', 'c2']).cumcount()
Out[4]:
0 0
1 1
2 0
3 1
4 0
5 1
6 2
7 0
8 0
9 0
10 1
11 2
dtype: int64
如果您希望从 1 开始订购
In [5]: df.groupby(['c1', 'c2']).cumcount()+1
Out[5]:
0 1
1 2
2 1
3 2
4 1
5 2
6 3
7 1
8 1
9 1
10 2
11 3
dtype: int64
2赞
Shaina Raza
5/12/2020
#2
这可能很有用
df = df.sort_values(['userID', 'date'])
grp = df.groupby('userID')['ItemID'].aggregate(lambda x: '->'.join(tuple(x))).reset_index()
print(grp)
2赞
cottontail
9/13/2022
#3
如果您有一个类似于下面的数据帧,并且您想通过从 or 构建它来添加列,即在其他列中保留类似值的运行计数(或直到出现标志),请继续阅读。seq
c1
c2
df = pd.DataFrame(
columns=" c1 c2 seq".split(),
data= [
[ "A", 1, 1 ],
[ "A1", 0, 2 ],
[ "A11", 0, 3 ],
[ "A111", 0, 4 ],
[ "B", 1, 1 ],
[ "B1", 0, 2 ],
[ "B111", 0, 3 ],
[ "C", 1, 1 ],
[ "C11", 0, 2 ] ])
然后首先找到组起始器,(下面使用(和)但可以使用任何创建布尔级数的方法,例如 、 等)并调用它来创建一个级数,其中每个组都有一个唯一的标识值。然后将其用作操作中的石斑鱼。str.contains()
eq()
lt()
ne()
isna()
cumsum()
groupby().cumsum()
总之,请使用类似于以下代码的代码。
# build a grouper Series for similar values
groups = df['c1'].str.contains("A$|B$|C$").cumsum()
# or build a grouper Series from flags (1s)
groups = df['c2'].eq(1).cumsum()
# groupby using the above grouper
df['seq'] = df.groupby(groups).cumcount().add(1)
0赞
CreekGeek
1/21/2023
#4
Jeff 的回答很简洁,但我更喜欢明确地排序......尽管通常不会覆盖这些类型的用例的 DF(例如 Shaina Raza 的答案)。
因此,要在每个(“c1”、“c2”)组中创建一个按“v1”排序的新列:
df["seq"] = df.sort_values(by=['c1','c2','v1']).groupby(['c1','c2']).cumcount()
您可以通过以下方式查看:
df.sort_values(by=['c1','c2','seq'])
或者,如果要覆盖 DF,则:
df = df.sort_values(by=['c1','c2','seq']).reset_index()
0赞
Siddhant Raj Mishra
8/7/2023
#5
您可以使用 groupby 和 cumcount 函数来实现所需的结果。
import pandas as pd
data = {'col': ['A', 'B', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'A']}
df = pd.DataFrame(data)
df['counts'] = df.groupby('col').cumcount() + 1
df
评论