Python Pandas 分类数据
通常情况下,实时数据包括文本列,这些文本列是重复性的。像性别、国家和代码这样的特征总是重复的。这些是分类数据的例子。
分类变量只能采取有限的,通常是固定数量的可能值。除了固定的长度,分类数据可能有一个顺序,但不能进行数字运算。分类是Pandas的一种数据类型。
分类数据类型在以下情况下是有用的
- 一个只由几个不同值组成的字符串变量。将这样的字符串变量转换为分类变量可以节省一些内存。
-
变量的词法顺序与逻辑顺序不一样(”一”、”二”、”三”)。通过转换为分类变量并指定分类的顺序,排序和最小/最大将使用逻辑顺序而不是词法顺序。
-
作为对其他python库的信号,此列应被视为分类变量(例如,使用合适的统计方法或绘图类型)。
对象创建
分类对象可以通过多种方式创建。不同的方式描述如下
类别
通过在创建pandas对象时指定dtype为 “类别”。
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]
传递给系列对象的元素数量是四个,但类别只有三个。在输出的Categories中观察到同样的情况。
pd.Categorical
使用标准的pandas Categorical构造函数,我们可以创建一个类别对象。
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]
从逻辑上讲,这个顺序意味着, a 大于 b , b 大于 c。
说明
在分类数据上使用 .describe() 命令,我们可以得到类似于字符串 类型 的 系列 或 数据框架 的输出。
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 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
获取类别的属性
obj.cat.categories 命令是用来获取 对象的类别。
import pandas as pd
import numpy as np
s = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
print s.categories
其 输出结果 如下 –
Index([u'b', u'a', u'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
该函数返回 错误 ,因为我们没有指定任何顺序。
重命名类别
重命名类别是通过给 series.cat.categories系列.cat.categories属性分配新值来完成的。
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
其 输出结果 如下 –
Index([u'Group a', u'Group b', u'Group c'], dtype='object')
初始类别 [ 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
其 输出结果 如下 –
Index([u'a', u'b', u'c', 4], dtype='object')
删除类别
使用 Categorical.remove_categories() 方法,不需要的类别可以被删除。
import pandas as pd
s = pd.Series(["a","b","c","a"], dtype="category")
print ("Original object:")
print s
print ("After removal:")
print s.cat.remove_categories("a")
其 输出结果 如下 –
Original object:
0 a
1 b
2 c
3 a
dtype: category
Categories (3, object): [a, b, c]
After removal:
0 NaN
1 b
2 c
3 NaN
dtype: category
Categories (2, object): [b, c]
分类数据的比较
在以下三种情况下,可以将分类数据与其他对象进行比较
- 与分类数据相同长度的列表类对象(列表、系列、数组…)进行平等比较(==和!=)。
-
所有分类数据与另一个分类系列的比较(==, !=, >, >=, <, <=),当ordered==True且类别相同时。
-
一个分类数据与一个标量的所有比较。
请看下面的例子 –
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
其 输出结果 如下 –
0 False
1 False
2 True
dtype: bool