2015-08-28 85 views
3

比方说,我有类别1到10,并且我想将red分配到值3到5,​​到1,6和7,blue到2,8,9和10。和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循环,它将通过值的字典并替换它们。有没有更优雅的解决这个问题?

+0

您是否只有一个要更改的系列,还是必须在整个数据框中发生? (顺便说一句,'pd.cat'是'df.cat'的拼写错误吗?我们通常使用'pd'作为熊猫的缩写。) – DSM

+0

抱歉,这是一种类型。它应该是一个dataFrame名称,我会解决它。但要回答你的问题,这只是一个系列/专栏。 –

回答

5

不确定优雅,但是如果你把旧到新的类别的字典,类似的信息(注意添加“紫”):

>>> 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())如果你确信所有分类值将在该列中可以看出。但是在这里,如果我们没有这样做,我们就不会在结果分类中看到purple,因为它是从它实际看到的类别构建而成的。

当然,如果你已经建立了你的清单['green','blue','red', etc.],直接使用它直接创建一个新的分类列并完全绕过这个映射也是一样简单。

+0

谢谢,这个作品! –

+0

我们应该将'k'解释为'new_name','v'为'old_name','vv'为'old_names',是否正确? – Chill2Macht

+0

看起来(如果我错了,请纠正我)上面给出的'.astype()'的第二个参数在没有被包含在set()中时不起作用(不管我们是否添加了'purple' ),因为那样我们会得到'类别必须是唯一的'错误(即因为没有首先将'm2.values()'传递给'set()'),'m2.values()'的元素不是唯一的。至少我得到了那个错误。只是传递'categorical'作为唯一的参数可以很好地提供所需的结果 - 现在加上一个警告现在传递给'.type()'的'categories'参数现在已被弃用。 – Chill2Macht