通常实时的数据包括重复的文本列。例如:性别,国家和代码等特征总是重复的。这些是分类数据的例子。
分类变量只能采用有限的数量,而且通常是固定的数量。除了固定长度,分类数据可能有顺序,但不能执行数字操作。 分类是Pandas数据类型。
分类数据类型在以下情况下非常有用 -
一个字符串变量,只包含几个不同的值。将这样的字符串变量转换为分类变量将会节省一些内存。
变量的词汇顺序与逻辑顺序("one","two","three")不同。 通过转换为分类并指定类别上的顺序,排序和最小/最大将使用逻辑顺序,而不是词法顺序。
作为其他python库的一个信号,这个列应该被当作一个分类变量(例如,使用合适的统计方法或plot类型)。
对象创建
分类对象可以通过多种方式创建。下面介绍了不同的方法 -
类别/分类
通过在pandas对象创建中将dtype指定为“category”。
import pandas as pd
s = pd.Series(["a","b","c","a"], dtype="category")
print (s)
0 a 1 b 2 c 3 a dtype: category Categories (3, object): ['a', 'b', 'c']
传递给系列对象的元素数量是四个,但类别只有三个。观察相同的输出类别。
pd.Categorical
使用标准Pandas分类构造函数,我们可以创建一个类别对象。语法如下 -
pandas.Categorical(values, categories, ordered)
举个例子 -
import pandas as pd
cat = pd.Categorical(['a', 'b', 'c', 'a', 'b', 'c'])
print (cat)
['a', 'b', 'c', 'a', 'b', 'c'] Categories (3, object): ['a', 'b', 'c']
再举一个例子 -
import pandas as pd
cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'])
print (cat)
['a', 'b', 'c', 'a', 'b', 'c', NaN] Categories (3, object): ['c', 'b', 'a']
这里,第二个参数表示类别。因此,在类别中不存在的任何值将被视为NaN。
现在,看看下面的例子 -
import pandas as pd
cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'],ordered=True)
print (cat)
['a', 'b', 'c', 'a', 'b', 'c', NaN] Categories (3, object): ['c' < 'b' < 'a']
从逻辑上讲,排序(ordered)意味着,a大于b,b大于c。
描述
使用分类数据上的.describe()命令,可以得到与类型字符串的Series或DataFrame类似的输出。
import pandas as pd
import numpy as np
cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
df = pd.DataFrame({"cat":cat, "s":["a", "c", "c", np.nan]})
print (df.describe())
print ("=============================")
print (df["cat"].describe())
cat s count 3 3 unique 2 2 top c c freq 2 2 ============================= count 3 unique 2 top c freq 2 Name: cat, dtype: object
import pandas as pd
import numpy as np
s = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
print (s.categories)
Index(['b', 'a', 'c'], dtype='object')
obj.ordered命令用于获取对象的顺序。
import pandas as pd
import numpy as np
cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
print (cat.ordered)
False
该函数返回结果为:False,因为这里没有指定任何顺序。
import pandas as pd
s = pd.Series(["a","b","c","a"], dtype="category")
s.cat.categories = ["Group %s" % g for g in s.cat.categories]
print (s.cat.categories)
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[9], line 4 1 import pandas as pd 3 s = pd.Series(["a","b","c","a"], dtype="category") ----> 4 s.cat.categories = ["Group %s" % g for g in s.cat.categories] 6 print (s.cat.categories) File /opt/conda/lib/python3.12/site-packages/pandas/core/base.py:178, in NoNewAttributesMixin.__setattr__(self, key, value) 172 if getattr(self, "__frozen", False) and not ( 173 key == "_cache" 174 or key in type(self).__dict__ 175 or getattr(self, key, None) is not None 176 ): 177 raise AttributeError(f"You cannot add any new attribute '{key}'") --> 178 object.__setattr__(self, key, value) File /opt/conda/lib/python3.12/site-packages/pandas/core/accessor.py:99, in PandasDelegate._add_delegate_accessors.<locals>._create_delegator_property.<locals>._setter(self, new_values) 98 def _setter(self, new_values): ---> 99 return self._delegate_property_set(name, new_values) File /opt/conda/lib/python3.12/site-packages/pandas/core/arrays/categorical.py:2915, in CategoricalAccessor._delegate_property_set(self, name, new_values) 2914 def _delegate_property_set(self, name: str, new_values): # type: ignore[override] -> 2915 return setattr(self._parent, name, new_values) AttributeError: property 'categories' of 'Categorical' object has no setter
初始类别[a,b,c]由对象的s.cat.categories属性更新。
附加新类别 使用Categorical.add.categories()方法,可以追加新的类别。
import pandas as pd
s = pd.Series(["a","b","c","a"], dtype="category")
s = s.cat.add_categories([4])
print (s.cat.categories)
import pandas as pd
s = pd.Series(["a","b","c","a"], dtype="category")
print ("Original object:")
s
print ("After removal:")
s.cat.remove_categories("a")
import pandas as pd
cat = pd.Series([1,2,3]).astype("category", categories=[1,2,3], ordered=True)
cat1 = pd.Series([2,2,2]).astype("category", categories=[1,2,3], ordered=True)
print (cat>cat1)