pandas:将多个类别合并为一个

新手上路,请多包涵

假设我有类别,1 到 10,我想分配 red 值 3 到 5, green 到 1,6 和 7,以及 blue 到 2、8、9 和 10。

我该怎么做?如果我尝试

df.cat.rename_categories(['red','green','blue'])

我得到一个错误: ValueError: new categories need to have the same number of items than the old categories! 但如果我把它放在

df.cat.rename_categories(['green','blue','red', 'red', 'red'
                        'green', 'green', 'blue', 'blue' 'blue'])

我会收到一条错误消息,指出存在重复值。

我能想到的唯一其他方法是编写一个 for 循环,它将遍历值的字典并替换它们。有没有更优雅的解决方法?

原文由 Minh Mai 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 405
2 个回答

不确定是否优雅,但如果您将旧类别改为新类别,例如(注意添加的“紫色”):

 >>> m = {"red": [3,4,5], "green": [1,6,7], "blue": [2,8,9,10], "purple": [11]}
>>> m2 = {v: k for k,vv in m.items() for v in vv}
>>> m2
{1: 'green', 2: 'blue', 3: 'red', 4: 'red', 5: 'red', 6: 'green',
 7: 'green', 8: 'blue', 9: 'blue', 10: 'blue', 11: 'purple'}

您可以使用它来构建一个新的分类系列:

 >>> df.cat.map(m2).astype("category", categories=set(m2.values()))
0    green
1     blue
2      red
3      red
4      red
5    green
6    green
7     blue
8     blue
9     blue
Name: cat, dtype: category
Categories (4, object): [green, purple, red, blue]

如果您确定所有分类值都将显示在列中,则不需要 categories=set(m2.values()) (如果您关心分类排序,则需要有序的等价物)。但是在这里,如果我们不这样做,我们就不会在生成的 Categorical 中看到 purple ,因为它是根据它实际看到的类别构建的。

当然,如果您已经构建了列表 ['green','blue','red', etc.] ,那么直接使用它来创建新的分类列并完全绕过此映射同样容易。

原文由 DSM 发布,翻译遵循 CC BY-SA 3.0 许可协议

似乎 pandas.explodepandas-0.25.0 一起发布--- (July 18, 2019) 将适合在那里,因此避免任何循环 -

 # Mapping dict
In [150]: m = {"red": [3,4,5], "green": [1,6,7], "blue": [2,8,9,10]}

In [151]: pd.Series(m).explode().sort_values()
Out[151]:
green     1
blue      2
red       3
red       4
red       5
green     6
green     7
blue      8
blue      9
blue     10
dtype: object

因此,结果是一个 pandas 系列,它具有来自 values:index 的所有必需映射。现在,根据用户需求,我们可以直接使用它,或者如果需要,可以使用不同的格式,如 dict 或 series,交换索引和值。让我们也探讨一下。

 # Mapping obtained
In [152]: s = pd.Series(m).explode().sort_values()

1)输出为字典:

 In [153]: dict(zip(s.values, s.index))
Out[153]:
{1: 'green',
 2: 'blue',
 3: 'red',
 4: 'red',
 5: 'red',
 6: 'green',
 7: 'green',
 8: 'blue',
 9: 'blue',
 10: 'blue'}

2)输出为系列:

 In [154]: pd.Series(s.index, s.values)
Out[154]:
1     green
2      blue
3       red
4       red
5       red
6     green
7     green
8      blue
9      blue
10     blue
dtype: object

原文由 Divakar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏