Pandas 减少 value_counts() 制表中的分类变量数量

Pandas reduce number of categorical variables in value_counts() tabulation

pandas 的新手我想执行类似于 的操作(分类变量的合并以降低它们的水平) 以下代码在 R

中运行良好
DTsetlvls <- function(x, newl)  
   setattr(x, "levels", c(setdiff(levels(x), newl), rep("other", length(newl))))

我的数据框:

df = pd.DataFrame({'Color': 'Red Red Blue'.split(),
                   'Value': [100, 150, 50]})

df['Counts'] = df.groupby('Color')['Value'].transform('count')
print (df)

  Color  Value  Counts
0   Red    100       2
1   Red    150       2
2  Blue     50       1

我会手动创建一个聚合列,然后基于该列标记频率较低的组,例如"blue" 作为一个 "other" 组。 但与简洁的 R 代码相比,这显得笨拙。这里正确的方法是什么?

您可以使用 value_counts with numpy.where, where is condition with isin

如果您的变量是对象类型,请参见下文。如果您的变量属于类别类型,则跳至底部。

df = pd.DataFrame({'Color':'Red Red Blue Red Violet Blue'.split(), 
                   'Value':[11,150,50,30,10,40]})
print (df)
    Color  Value
0     Red     11
1     Red    150
2    Blue     50
3     Red     30
4  Violet     10
5    Blue     40

a = df.Color.value_counts()
print (a)
Red       3
Blue      2
Violet    1
Name: Color, dtype: int64

#get top 2 values of index
vals = a[:2].index
print (vals)
Index(['Red', 'Blue'], dtype='object')

df['new'] = np.where(df.Color.isin(vals), 0,1)
print (df)
    Color  Value  new
0     Red     11    0
1     Red    150    0
2    Blue     50    0
3     Red     30    0
4  Violet     10    1
5    Blue     40    0

或者如果需要替换所有非最高值使用 where:

df['new1'] = df.Color.where(df.Color.isin(vals), 'other')
print (df)
    Color  Value   new1
0     Red     11    Red
1     Red    150    Red
2    Blue     50   Blue
3     Red     30    Red
4  Violet     10  other
5    Blue     40   Blue

类别类型:

df = pd.DataFrame({'Color':'Red Red Blue Red Violet Blue'.split(), 
                   'Value':[11,150,50,30,10,40]})
df.Color = df.Color.astype('category')

a= df.Color.value_counts()[:2].index
print(a)
CategoricalIndex(['Red', 'Blue'], 
                categories=['Blue', 'Red', 'Violet'], 
                ordered=False, dtype='category')

请注意,紫色仍然是一个类别。所以我们需要 .remove_unused_categories().

vals = df.Color.value_counts()[:2].index.remove_unused_categories()
CategoricalIndex(['Red', 'Blue'], 
                 categories=['Blue', 'Red'], 
                 ordered=False, dtype='category')

如评论中所述,设置新变量时会出现ValueError。解决方法是改变类型。

df['new1'] = df.Color.astype('object').where(df.Color.isin(vals), 'other')
df['new1'] = df['new1'].astype('category')