如何使用 pandas 条件提取组列表元素
How to extract group list element using pandas criteria
我有一个 pandas 数据框,如下所示
ID,color
1, Yellow
1, Red
1, Green
2, Red
2, np.nan
3, Green
3, Red
3, Green
4, Yellow
4, Red
5, Green
5, np.nan
6, Red
7, Red
fd = pd.read_clipboard(sep=',')
正如您在输入数据框中看到的那样,某些 ID 具有多种关联的颜色。
因此,每当有多种颜色与之关联时,我希望根据以下标准select只使用一种颜色
['Green','Red','Yellow'] = Choose 'Green'
['Red', 'Yellow'] = Choose 'Yellow'
['Green', 'Yellow'] = Choose 'Green'
基本上,绿色是第一优先。第二个偏好是黄色,最后一个偏好是红色。
所以,如果一个ID只要有绿色,就选择绿色(其他颜色不用管)。
如果一个ID只要有黄色和红色,就选择黄色
如果其所有行的 ID 只有 NA
,则将其保留为 NA
我尝试了下面的方法,但这只会让我得到颜色列表
fd.groupby('ID',as_index=False)['color'].aggregate(lambda x: list(x))
fd[final_color] = [if i[0] =='Green' for i in fd[col]]
我希望我的输出如下所示
更新
解决此问题的一种方法是实施自定义排序:
sort_preference = {
'Green': 0,
'Yellow': 1,
}
(
fd
.sort_values(by=['color'], key=lambda x: x.map(sort_preference))
.groupby('ID')
.head(1)
)
在偏好字典的帮助下,根据颜色对数据帧的值进行排序,然后删除 ID
上的重复项
d = {'Green': 1, 'Yellow': 2, 'Red': 3}
df.sort_values('color', key=lambda c: c.map(d)).drop_duplicates('ID')
替代方法首先将 color
列转换为 有序分类类型 ,然后分组并聚合为 select 最小值
df['color'] = pd.Categorical(df['color'], ['Green', 'Yellow', 'Red'], True)
df.groupby('ID', as_index=False)['color'].agg('min')
ID color
0 1 Green
1 2 Red
2 3 Green
3 4 Yellow
4 5 Green
5 6 Red
6 7 Red
不进行排序,如果您将颜色映射到数值,则可以使用 idxmin
:
d = {'Green': 1, 'Yellow': 2, 'Red': 3}
out = df.loc[df.assign(num=df['color'].map(d)).groupby('ID')['num'].idxmin()]
print(out)
# Output
ID color
2 1 Green
3 2 Red
5 3 Green
8 4 Yellow
10 5 Green
12 6 Red
13 7 Red
我有一个 pandas 数据框,如下所示
ID,color
1, Yellow
1, Red
1, Green
2, Red
2, np.nan
3, Green
3, Red
3, Green
4, Yellow
4, Red
5, Green
5, np.nan
6, Red
7, Red
fd = pd.read_clipboard(sep=',')
正如您在输入数据框中看到的那样,某些 ID 具有多种关联的颜色。
因此,每当有多种颜色与之关联时,我希望根据以下标准select只使用一种颜色
['Green','Red','Yellow'] = Choose 'Green'
['Red', 'Yellow'] = Choose 'Yellow'
['Green', 'Yellow'] = Choose 'Green'
基本上,绿色是第一优先。第二个偏好是黄色,最后一个偏好是红色。
所以,如果一个ID只要有绿色,就选择绿色(其他颜色不用管)。
如果一个ID只要有黄色和红色,就选择黄色
如果其所有行的 ID 只有 NA
,则将其保留为 NA
我尝试了下面的方法,但这只会让我得到颜色列表
fd.groupby('ID',as_index=False)['color'].aggregate(lambda x: list(x))
fd[final_color] = [if i[0] =='Green' for i in fd[col]]
我希望我的输出如下所示
更新
解决此问题的一种方法是实施自定义排序:
sort_preference = {
'Green': 0,
'Yellow': 1,
}
(
fd
.sort_values(by=['color'], key=lambda x: x.map(sort_preference))
.groupby('ID')
.head(1)
)
在偏好字典的帮助下,根据颜色对数据帧的值进行排序,然后删除 ID
d = {'Green': 1, 'Yellow': 2, 'Red': 3}
df.sort_values('color', key=lambda c: c.map(d)).drop_duplicates('ID')
替代方法首先将 color
列转换为 有序分类类型 ,然后分组并聚合为 select 最小值
df['color'] = pd.Categorical(df['color'], ['Green', 'Yellow', 'Red'], True)
df.groupby('ID', as_index=False)['color'].agg('min')
ID color
0 1 Green
1 2 Red
2 3 Green
3 4 Yellow
4 5 Green
5 6 Red
6 7 Red
不进行排序,如果您将颜色映射到数值,则可以使用 idxmin
:
d = {'Green': 1, 'Yellow': 2, 'Red': 3}
out = df.loc[df.assign(num=df['color'].map(d)).groupby('ID')['num'].idxmin()]
print(out)
# Output
ID color
2 1 Green
3 2 Red
5 3 Green
8 4 Yellow
10 5 Green
12 6 Red
13 7 Red