使用 pandas 根据组内排名顺序创建新列
using pandas to create new columns based on intra-group rank-order
我有一个包含大量行的 pandas DataFrame。我正在尝试根据成员的组内排名顺序为框架创建新列。这是一些假数据,说明了我所拥有的:
Num_members = int(1.e7)
Num_groups = int(1.e5)
members = pd.DataFrame({
'ID': np.arange(Num_members),
'groupID': np.random.random_integers(0, 2*Num_groups, Num_members),
'groupmass': np.zeros(Num_members),
'brightness': np.random.uniform(8,12, Num_members),
'color':np.random.uniform(0,1,Num_members)
})
我正在尝试为成员创建两个新列:
亮度的组内排序,所以最亮的
一个组的成员将获得 0 的值,下一个最亮的 1,等等
组中最亮成员的颜色。因此,对于此列,同一组的所有成员都将被分配相同的值,该值等于组内 brightness-rank=0 的成员的 'color'。
我知道 groupby 操作正是为这种操作而设计的,但我一直无法弄清楚如何正确地执行此操作。速度是一个重要问题,因为我的数据集很大,我需要在 MCMC 似然分析中执行此操作。
这是我的玩具示例:
import pandas as pd
import numpy as np
numpy.random.seed(42)
Num_members = int(10)
Num_groups = int(1)
members = pd.DataFrame({
'ID': np.arange(Num_members),
'groupID': np.random.random_integers(0, 2*Num_groups, Num_members),
'groupmass': np.zeros(Num_members),
'brightness': np.random.uniform(8,12, Num_members),
'color':np.random.uniform(0,1,Num_members)
})
使用计算亮度等级和最大值的自定义函数:
def rank_max_fun(df):
df["b_rank"] = df.brightness.rank(ascending=False)
df["b_max"] = df.brightness.max()
return df
分组和应用
df = members.groupby("groupID", sort=False).apply(rank_max_fun)
产量:
ID brightness color groupID groupmass b_rank b_max
0 0 8.232334 0.304242 2 0 6 11.329771
1 1 11.464705 0.524756 0 0 2 11.879639
2 2 10.404460 0.431945 2 0 3 11.329771
3 3 10.832290 0.291229 2 0 2 11.329771
4 4 8.082338 0.611853 0 0 3 11.879639
5 5 11.879639 0.139494 0 0 1 11.879639
6 6 11.329771 0.292145 2 0 1 11.329771
7 7 8.849356 0.366362 1 0 1 8.849356
8 8 8.727300 0.456070 2 0 5 11.329771
9 9 8.733618 0.785176 2 0 4 11.329771
缺点:在大型数据集上需要相当长的时间。
我再试一次:
import pandas as pd
import numpy as np
np.random.seed(42)
Num_members = int(10)
Num_groups = int(1)
members = pd.DataFrame({
'ID': np.arange(Num_members),
'groupID': np.random.random_integers(0, 2*Num_groups, Num_members),
'groupmass': np.zeros(Num_members),
'brightness': np.random.uniform(8,12, Num_members),
'color':np.random.uniform(0,1,Num_members)
})
逻辑:
df = members.groupby("groupID").agg({"brightness": np.max})
df = df.reset_index()
df = df.merge(members[["groupID", "brightness", "color"]], on=("groupID", "brightness"))
首先我们进行分组以找到最大值 brightness
。之后,我们将 df
与 members
结合起来,得到具有最高 brightness
值的成员的 color
值。基本上,我们合并 members
和 df
中的所有行,它们具有与 brightness
和 groupID
.
相同的值
请注意,如果一个组中有多个值具有最大分数,这可能会导致意外的行重复。
df
现在看起来如下:
groupID brightness color
0 0 11.879639 0.139494
1 1 8.849356 0.366362
2 2 11.329771 0.292145
对于每个组,它包含 groupID
、brightness
的最大值和具有最大亮度值的元素的 color
。
我们现在可以合并数据帧 members
和 df
:
result = members.merge(df, on="groupID", suffixes=("_member", "_group"))
并得到以下结果:
ID brightness_member color_member groupID groupmass brightness_group color_group
0 0 8.232334 0.304242 2 0 11.329771 0.292145
1 2 10.404460 0.431945 2 0 11.329771 0.292145
2 3 10.832290 0.291229 2 0 11.329771 0.292145
3 6 11.329771 0.292145 2 0 11.329771 0.292145
4 8 8.727300 0.456070 2 0 11.329771 0.292145
5 9 8.733618 0.785176 2 0 11.329771 0.292145
6 1 11.464705 0.524756 0 0 11.879639 0.139494
7 4 8.082338 0.611853 0 0 11.879639 0.139494
8 5 11.879639 0.139494 0 0 11.879639 0.139494
9 7 8.849356 0.366362 1 0 8.849356 0.366362
我有一个包含大量行的 pandas DataFrame。我正在尝试根据成员的组内排名顺序为框架创建新列。这是一些假数据,说明了我所拥有的:
Num_members = int(1.e7)
Num_groups = int(1.e5)
members = pd.DataFrame({
'ID': np.arange(Num_members),
'groupID': np.random.random_integers(0, 2*Num_groups, Num_members),
'groupmass': np.zeros(Num_members),
'brightness': np.random.uniform(8,12, Num_members),
'color':np.random.uniform(0,1,Num_members)
})
我正在尝试为成员创建两个新列:
亮度的组内排序,所以最亮的 一个组的成员将获得 0 的值,下一个最亮的 1,等等
组中最亮成员的颜色。因此,对于此列,同一组的所有成员都将被分配相同的值,该值等于组内 brightness-rank=0 的成员的 'color'。
我知道 groupby 操作正是为这种操作而设计的,但我一直无法弄清楚如何正确地执行此操作。速度是一个重要问题,因为我的数据集很大,我需要在 MCMC 似然分析中执行此操作。
这是我的玩具示例:
import pandas as pd
import numpy as np
numpy.random.seed(42)
Num_members = int(10)
Num_groups = int(1)
members = pd.DataFrame({
'ID': np.arange(Num_members),
'groupID': np.random.random_integers(0, 2*Num_groups, Num_members),
'groupmass': np.zeros(Num_members),
'brightness': np.random.uniform(8,12, Num_members),
'color':np.random.uniform(0,1,Num_members)
})
使用计算亮度等级和最大值的自定义函数:
def rank_max_fun(df):
df["b_rank"] = df.brightness.rank(ascending=False)
df["b_max"] = df.brightness.max()
return df
分组和应用
df = members.groupby("groupID", sort=False).apply(rank_max_fun)
产量:
ID brightness color groupID groupmass b_rank b_max
0 0 8.232334 0.304242 2 0 6 11.329771
1 1 11.464705 0.524756 0 0 2 11.879639
2 2 10.404460 0.431945 2 0 3 11.329771
3 3 10.832290 0.291229 2 0 2 11.329771
4 4 8.082338 0.611853 0 0 3 11.879639
5 5 11.879639 0.139494 0 0 1 11.879639
6 6 11.329771 0.292145 2 0 1 11.329771
7 7 8.849356 0.366362 1 0 1 8.849356
8 8 8.727300 0.456070 2 0 5 11.329771
9 9 8.733618 0.785176 2 0 4 11.329771
缺点:在大型数据集上需要相当长的时间。
我再试一次:
import pandas as pd
import numpy as np
np.random.seed(42)
Num_members = int(10)
Num_groups = int(1)
members = pd.DataFrame({
'ID': np.arange(Num_members),
'groupID': np.random.random_integers(0, 2*Num_groups, Num_members),
'groupmass': np.zeros(Num_members),
'brightness': np.random.uniform(8,12, Num_members),
'color':np.random.uniform(0,1,Num_members)
})
逻辑:
df = members.groupby("groupID").agg({"brightness": np.max})
df = df.reset_index()
df = df.merge(members[["groupID", "brightness", "color"]], on=("groupID", "brightness"))
首先我们进行分组以找到最大值 brightness
。之后,我们将 df
与 members
结合起来,得到具有最高 brightness
值的成员的 color
值。基本上,我们合并 members
和 df
中的所有行,它们具有与 brightness
和 groupID
.
请注意,如果一个组中有多个值具有最大分数,这可能会导致意外的行重复。
df
现在看起来如下:
groupID brightness color
0 0 11.879639 0.139494
1 1 8.849356 0.366362
2 2 11.329771 0.292145
对于每个组,它包含 groupID
、brightness
的最大值和具有最大亮度值的元素的 color
。
我们现在可以合并数据帧 members
和 df
:
result = members.merge(df, on="groupID", suffixes=("_member", "_group"))
并得到以下结果:
ID brightness_member color_member groupID groupmass brightness_group color_group
0 0 8.232334 0.304242 2 0 11.329771 0.292145
1 2 10.404460 0.431945 2 0 11.329771 0.292145
2 3 10.832290 0.291229 2 0 11.329771 0.292145
3 6 11.329771 0.292145 2 0 11.329771 0.292145
4 8 8.727300 0.456070 2 0 11.329771 0.292145
5 9 8.733618 0.785176 2 0 11.329771 0.292145
6 1 11.464705 0.524756 0 0 11.879639 0.139494
7 4 8.082338 0.611853 0 0 11.879639 0.139494
8 5 11.879639 0.139494 0 0 11.879639 0.139494
9 7 8.849356 0.366362 1 0 8.849356 0.366362