将组的顺序计数器列添加到 pandas 数据框
- 2024-11-20 08:44:00
- admin 原创
- 8
问题描述:
我觉得有比这更好的方法:
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
有没有办法可以避免回调?
解决方案 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:
这可能有用
df = df.sort_values(['userID', 'date'])
grp = df.groupby('userID')['ItemID'].aggregate(lambda x: '->'.join(tuple(x))).reset_index()
print(grp)
它将创建一个像这样的序列
解决方案 3:
如果您有一个类似于下面的数据框,并且想要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)
解决方案 4:
您可以使用 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
解决方案 5:
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()
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD