[英]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
有没有办法避免回调?
使用
cumcount()<\/code> ,请参阅
此处<\/a>的文档
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
这可能有用
df = df.sort_values(['userID', 'date'])
grp = df.groupby('userID')['ItemID'].aggregate(lambda x: '->'.join(tuple(x))).reset_index()
print(grp)
完整的工作代码
import pandas as pd
df = pd.DataFrame(
[['A', 'X', 3], ['A', 'X', 5], ['A', 'Y', 7], ['A', 'Y', 1],
['B', 'X', 3], ['B', 'X', 1], ['B', 'X', 3], ['B', 'Y', 1],
['C', 'X', 7], ['C', 'Y', 4], ['C', 'Y', 1], ['C', 'Y', 6]],
columns=['c1', 'c2', 'v1'])
df['seq'] = df.groupby(['c1', 'c2']).cumcount() + 1
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
如果您有一个类似于下面的 dataframe 并且您想通过从c1
构建它来添加seq
列,请继续阅读。
df = pd.DataFrame(
columns=" c1 seq".split(),
data= [
[ "A", 1 ],
[ "A1", 2 ],
[ "A11", 3 ],
[ "A111", 4 ],
[ "B", 1 ],
[ "B1", 2 ],
[ "B111", 3 ],
[ "C", 1 ],
[ "C11", 2 ] ])
然后首先找到组起始者( str.contains()
在下面使用,但也可以使用eq()
, lt()
, ne()
等)并在其上调用cumsum()
以创建一个系列,其中每个组都有一个唯一的识别价值。 然后将其用作groupby().cumsum()
操作的分组器。
总之,使用类似于下面的代码。
# build a grouper Series
groups = df['c1'].str.contains("A$|B$|C$").cumsum()
# groupby using the above grouper
df['seq'] = df.groupby(groups).cumcount().add(1)
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.