将排名应用于 Pandas Groupby 中的每个组
Applying Ranks to every group in Pandas Groupby
假设我有一个像这样的简单数据集(即 df1):
ID Name Max_FileID
--------------------------------
1 Dog 3
1 Dog 3
1 Dog 3
2 Bird 1
3 Cat 5
3 Cat 5
我想按 ID 对数据集进行分组(我对此没有问题):
df1.groupby('ID')
然后使用 Max_FileID + Rank 添加一个新列。
结果应该是这样的
ID Name Max_FileID Rank
------------------------------------------
1 Dog 3 4
1 Dog 3 5
1 Dog 3 6
2 Bird 1 2
3 Cat 5 6
3 Cat 5 7
为了帮助更好地理解我想要实现的目标,这里有一个 SQL 等价物:
SELECT
ID,
Name,
Max_FileID,
Max_FileID + ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID)
FROM df1
此外,我创建了一个自定义函数:
def sequential_ranking(self, iterable, max_id):
try:
max_id = max_id - 1
seq_nums = list()
for num in iterable:
max_id += 1
seq_nums.append(max_id)
return seq_nums
不确定是否有内置函数。提前致谢!!
您可以使用 groupby,然后通过添加 np.arange:
来应用自定义转换
df['Rank'] = df.groupby('ID')['Max_FileID'].transform(lambda x: x+np.arange(1, len(x)+1))
您可以使用 DataFrameGroupBy.rank
函数,其中 returns 组中的排名值,如果您将方法参数指定为 first
,则排名将按照它们在组中出现的顺序进行分配.
你可以使用这个:
df["Rank"] = df["Max_FileID"] + df.groupby("ID")["Max_FileID"].rank(method="first").astype(int)
结果:
>>> print(df)
ID Name Max_FileID Rank
0 1 Dog 3 4
1 1 Dog 3 5
2 1 Dog 3 6
3 2 Bird 1 2
4 3 Cat 5 6
5 3 Cat 5 7
你给出的例子有点像你说的那样令人困惑 "then add a new column using Max_FileID + Rank" 但这个例子调用了新列 "Rank" 即使它看起来像 Rank 和 Max_FileID 的总和。
我认为你只需要使用 groupby().rank()
如果不需要,你可以删除中间的 'rank' 列。
df['rank'] = df.groupby('ID').rank(method='first').astype(int)
df['newcol'] = df['Max_FileID'] + df['rank']
输出
df
=== Output: ===
ID Name Max_FileID rank newcol
0 1 Dog 3 1 4
1 1 Dog 3 2 5
2 1 Dog 3 3 6
3 2 Bird 1 1 2
4 3 Cat 5 1 6
5 3 Cat 5 2 7
假设我有一个像这样的简单数据集(即 df1):
ID Name Max_FileID
--------------------------------
1 Dog 3
1 Dog 3
1 Dog 3
2 Bird 1
3 Cat 5
3 Cat 5
我想按 ID 对数据集进行分组(我对此没有问题):
df1.groupby('ID')
然后使用 Max_FileID + Rank 添加一个新列。
结果应该是这样的
ID Name Max_FileID Rank
------------------------------------------
1 Dog 3 4
1 Dog 3 5
1 Dog 3 6
2 Bird 1 2
3 Cat 5 6
3 Cat 5 7
为了帮助更好地理解我想要实现的目标,这里有一个 SQL 等价物:
SELECT
ID,
Name,
Max_FileID,
Max_FileID + ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID)
FROM df1
此外,我创建了一个自定义函数:
def sequential_ranking(self, iterable, max_id):
try:
max_id = max_id - 1
seq_nums = list()
for num in iterable:
max_id += 1
seq_nums.append(max_id)
return seq_nums
不确定是否有内置函数。提前致谢!!
您可以使用 groupby,然后通过添加 np.arange:
来应用自定义转换df['Rank'] = df.groupby('ID')['Max_FileID'].transform(lambda x: x+np.arange(1, len(x)+1))
您可以使用 DataFrameGroupBy.rank
函数,其中 returns 组中的排名值,如果您将方法参数指定为 first
,则排名将按照它们在组中出现的顺序进行分配.
你可以使用这个:
df["Rank"] = df["Max_FileID"] + df.groupby("ID")["Max_FileID"].rank(method="first").astype(int)
结果:
>>> print(df)
ID Name Max_FileID Rank
0 1 Dog 3 4
1 1 Dog 3 5
2 1 Dog 3 6
3 2 Bird 1 2
4 3 Cat 5 6
5 3 Cat 5 7
你给出的例子有点像你说的那样令人困惑 "then add a new column using Max_FileID + Rank" 但这个例子调用了新列 "Rank" 即使它看起来像 Rank 和 Max_FileID 的总和。
我认为你只需要使用 groupby().rank()
如果不需要,你可以删除中间的 'rank' 列。
df['rank'] = df.groupby('ID').rank(method='first').astype(int)
df['newcol'] = df['Max_FileID'] + df['rank']
输出
df
=== Output: ===
ID Name Max_FileID rank newcol
0 1 Dog 3 1 4
1 1 Dog 3 2 5
2 1 Dog 3 3 6
3 2 Bird 1 1 2
4 3 Cat 5 1 6
5 3 Cat 5 2 7