• Pandas 分类数据


     

    这是对Pandas分类数据类型的介绍,包括与R的简短比较factor

    Categoricals是与统计信息中的分类变量相对应的Pandas数据类型。分类变量具有有限的且通常是固定数量的可能值(R中的categorieslevels)。例子包括性别,社会阶层,血型,国家归属,观察时间或通过李克特量表的评分。

    与统计分类变量相比,分类数据可能具有顺序(例如“强烈同意”与“同意”或“第一次观察”与“第二次观察”),但是数字运算(加法,除法……)是不可能的。

    分类数据的所有值都在categories或中np.nan顺序由的顺序定义categories,而不是值的词法顺序。在内部,数据结构由一个categories数组和一个整数数组组成,该整数数组codes指向数组中的实数值categories

    在以下情况下,分类数据类型很有用:

    • 一个仅包含几个不同值的字符串变量。将这样的字符串变量转换为分类变量将节省一些内存,请参见此处

    • 变量的词法顺序与逻辑顺序(“一个”,“两个”,“三个”)不同。通过转换为类别并在类别上指定顺序,排序和最小/最大将使用逻辑顺序而不是词汇顺序,请参见此处

    • 作为其他Python库的信号,此列应视为类别变量(例如,使用适当的统计方法或绘图类型)。

    另请参阅有关类别API文档

    创建对象

    系列创建

    可以通过几种方式创建类别中的类别Series或列DataFrame

    通过指定dtype="category"在构造时Series

    In [1]: s = pd.Series(["a", "b", "c", "a"], dtype="category")
    
    In [2]: s
    Out[2]: 
    0    a
    1    b
    2    c
    3    a
    dtype: category
    Categories (3, object): ['a', 'b', 'c']
    

    通过将现有的Series或列转换为categorydtype:

    In [3]: df = pd.DataFrame({"A": ["a", "b", "c", "a"]})
    
    In [4]: df["B"] = df["A"].astype("category")
    
    In [5]: df
    Out[5]: 
       A  B
    0  a  a
    1  b  b
    2  c  c
    3  a  a
    

    通过使用特殊功能(例如)cut(),可以将数据分组为离散的bin。请参阅文档中有关平铺示例

    In [6]: df = pd.DataFrame({"value": np.random.randint(0, 100, 20)})
    
    In [7]: labels = ["{0} - {1}".format(i, i + 9) for i in range(0, 100, 10)]
    
    In [8]: df["group"] = pd.cut(df.value, range(0, 105, 10), right=False, labels=labels)
    
    In [9]: df.head(10)
    Out[9]: 
       value    group
    0     65  60 - 69
    1     49  40 - 49
    2     56  50 - 59
    3     43  40 - 49
    4     43  40 - 49
    5     91  90 - 99
    6     32  30 - 39
    7     87  80 - 89
    8     36  30 - 39
    9      8    0 - 9
    

    通过将pandas.Categorical对象传递给Series或将其分配给DataFrame

    In [10]: raw_cat = pd.Categorical(
       ....:     ["a", "b", "c", "a"], categories=["b", "c", "d"], ordered=False
       ....: )
       ....: 
    
    In [11]: s = pd.Series(raw_cat)
    
    In [12]: s
    Out[12]: 
    0    NaN
    1      b
    2      c
    3    NaN
    dtype: category
    Categories (3, object): ['b', 'c', 'd']
    
    In [13]: df = pd.DataFrame({"A": ["a", "b", "c", "a"]})
    
    In [14]: df["B"] = raw_cat
    
    In [15]: df
    Out[15]: 
       A    B
    0  a  NaN
    1  b    b
    2  c    c
    3  a  NaN
    

    分类数据具有特定的category dtype

    In [16]: df.dtypes
    Out[16]: 
    A      object
    B    category
    dtype: object
    

    DataFrame创建

    与上一节中将单个列转换为分类的部分相似,DataFrame可以在构造过程中或之后将a中的所有列 批量转换为分类的对象。

    这可以在施工期间通过指定完成dtype="category"DataFrame构造函数:

    In [17]: df = pd.DataFrame({"A": list("abca"), "B": list("bccd")}, dtype="category")
    
    In [18]: df.dtypes
    Out[18]: 
    A    category
    B    category
    dtype: object
    

    请注意,每一列中存在的类别有所不同;转换是逐列完成的,因此只有给定列中存在的标签才是类别:

    In [19]: df["A"]
    Out[19]: 
    0    a
    1    b
    2    c
    3    a
    Name: A, dtype: category
    Categories (3, object): ['a', 'b', 'c']
    
    In [20]: df["B"]
    Out[20]: 
    0    b
    1    c
    2    c
    3    d
    Name: B, dtype: category
    Categories (3, object): ['b', 'c', 'd']
    

    类似地,DataFrame可以使用DataFrame.astype()以下命令批量转换现有中的所有列

    In [21]: df = pd.DataFrame({"A": list("abca"), "B": list("bccd")})
    
    In [22]: df_cat = df.astype("category")
    
    In [23]: df_cat.dtypes
    Out[23]: 
    A    category
    B    category
    dtype: object
    

    此转换也逐列完成:

    In [24]: df_cat["A"]
    Out[24]: 
    0    a
    1    b
    2    c
    3    a
    Name: A, dtype: category
    Categories (3, object): ['a', 'b', 'c']
    
    In [25]: df_cat["B"]
    Out[25]: 
    0    b
    1    c
    2    c
    3    d
    Name: B, dtype: category
    Categories (3, object): ['b', 'c', 'd']
    

    控制行为

    在上面传递的示例中dtype='category',我们使用了默认行为:

    1. 从数据推断类别。

    2. 类别是无序的。

    要控制这些行为,请'category'使用的实例代替传递CategoricalDtype

    In [26]: from pandas.api.types import CategoricalDtype
    
    In [27]: s = pd.Series(["a", "b", "c", "a"])
    
    In [28]: cat_type = CategoricalDtype(categories=["b", "c", "d"], ordered=True)
    
    In [29]: s_cat = s.astype(cat_type)
    
    In [30]: s_cat
    Out[30]: 
    0    NaN
    1      b
    2      c
    3    NaN
    dtype: category
    Categories (3, object): ['b' < 'c' < 'd']
    

    同样,CategoricalDtype可以将a与aDataFrame一起使用,以确保所有列之间的类别保持一致。

    In [31]: from pandas.api.types import CategoricalDtype
    
    In [32]: df = pd.DataFrame({"A": list("abca"), "B": list("bccd")})
    
    In [33]: cat_type = CategoricalDtype(categories=list("abcd"), ordered=True)
    
    In [34]: df_cat = df.astype(cat_type)
    
    In [35]: df_cat["A"]
    Out[35]: 
    0    a
    1    b
    2    c
    3    a
    Name: A, dtype: category
    Categories (4, object): ['a' < 'b' < 'c' < 'd']
    
    In [36]: df_cat["B"]
    Out[36]: 
    0    b
    1    c
    2    c
    3    d
    Name: B, dtype: category
    Categories (4, object): ['a' < 'b' < 'c' < 'd']
    

    注意

    要执行逐表转换,其中将全部中的所有标签DataFrame用作每一列的类别,则categories可以通过编程地确定参数 categories pd.unique(df.to_numpy().ravel())

    如果已经拥有codescategories,则可以使用 from_codes()构造函数在常规构造函数模式下保存分解步骤:

    In [37]: splitter = np.random.choice([0, 1], 5, p=[0.5, 0.5])
    
    In [38]: s = pd.Series(pd.Categorical.from_codes(splitter, categories=["train", "test"]))
    

    恢复原始数据

    要返回原始Series数组或NumPy数组,请使用 Series.astype(original_dtype)np.asarray(categorical)

    In [39]: s = pd.Series(["a", "b", "c", "a"])
    
    In [40]: s
    Out[40]: 
    0    a
    1    b
    2    c
    3    a
    dtype: object
    
    In [41]: s2 = s.astype("category")
    
    In [42]: s2
    Out[42]: 
    0    a
    1    b
    2    c
    3    a
    dtype: category
    Categories (3, object): ['a', 'b', 'c']
    
    In [43]: s2.astype(str)
    Out[43]: 
    0    a
    1    b
    2    c
    3    a
    dtype: object
    
    In [44]: np.asarray(s2)
    Out[44]: array(['a', 'b', 'c', 'a'], dtype=object)
    

    注意

    与Rfactor函数相反,分类数据不会将输入值转换为字符串;类别最终将具有与原始值相同的数据类型。

    注意

    与R的factor功能相反,当前无法在创建时分配/更改标签。用于categories在创建时间之后更改类别。

    CategoricalDtype 

    类别的类型由

    1. categories:唯一值序列,无缺失值

    2. ordered:一个布尔值

    此信息可以存储在中CategoricalDtypecategories参数是可选的,这意味着应根据pandas.Categorical创建时数据中存在的内容推断实际类别 默认情况下,假定类别为无序的。

    In [45]: from pandas.api.types import CategoricalDtype
    
    In [46]: CategoricalDtype(["a", "b", "c"])
    Out[46]: CategoricalDtype(categories=['a', 'b', 'c'], ordered=False)
    
    In [47]: CategoricalDtype(["a", "b", "c"], ordered=True)
    Out[47]: CategoricalDtype(categories=['a', 'b', 'c'], ordered=True)
    
    In [48]: CategoricalDtype()
    Out[48]: CategoricalDtype(categories=None, ordered=False)
    

    ACategoricalDtype可以在Pandas希望使用的任何地方使用dtype例如pandas.read_csv(),, pandas.DataFrame.astype()或在Series构造函数中。

    注意

    为方便起见,当您希望类别的默认行为无序且等于数组中的设置值时,可以使用字符串'category'代替a CategoricalDtype换句话说,dtype='category'等于 dtype=CategoricalDtype()

    平等语义

    CategoricalDtype只要具有相同的类别和顺序,两个compare实例就相等。比较两个无序分类时,categories不考虑的顺序

    In [49]: c1 = CategoricalDtype(["a", "b", "c"], ordered=False)
    
    # Equal, since order is not considered when ordered=False
    In [50]: c1 == CategoricalDtype(["b", "c", "a"], ordered=False)
    Out[50]: True
    
    # Unequal, since the second CategoricalDtype is ordered
    In [51]: c1 == CategoricalDtype(["a", "b", "c"], ordered=True)
    Out[51]: False
    

    所有CategoricalDtypecompare的实例都等于string 'category'

    In [52]: c1 == "category"
    Out[52]: True
    

    警告

    因为dtype='category'本质上是,并且由于所有实例都等于,所以所有实例比较都等于a ,而与或 无关CategoricalDtype(None, False)CategoricalDtype'category'CategoricalDtypeCategoricalDtype(None, False)categoriesordered

    描述

    describe()对分类数据使用会产生与SeriesDataFrame类型相似的输出string

    In [53]: cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
    
    In [54]: df = pd.DataFrame({"cat": cat, "s": ["a", "c", "c", np.nan]})
    
    In [55]: df.describe()
    Out[55]: 
           cat  s
    count    3  3
    unique   2  2
    top      c  c
    freq     2  2
    
    In [56]: df["cat"].describe()
    Out[56]: 
    count     3
    unique    2
    top       c
    freq      2
    Name: cat, dtype: object
    

    使用类别

    分类数据具有categoriesordered属性,该属性列出了它们的可能值以及排序是否重要。这些属性在s.cat.categories中公开s.cat.ordered如果您不手动指定类别和顺序,则可以从传递的参数中推断出它们。

    In [57]: s = pd.Series(["a", "b", "c", "a"], dtype="category")
    
    In [58]: s.cat.categories
    Out[58]: Index(['a', 'b', 'c'], dtype='object')
    
    In [59]: s.cat.ordered
    Out[59]: False
    

    也可以按特定顺序传递类别:

    In [60]: s = pd.Series(pd.Categorical(["a", "b", "c", "a"], categories=["c", "b", "a"]))
    
    In [61]: s.cat.categories
    Out[61]: Index(['c', 'b', 'a'], dtype='object')
    
    In [62]: s.cat.ordered
    Out[62]: False
    

    注意

    新的分类数据不会自动排序。您必须明确传递ordered=True以指示已订购Categorical

    注意

    的结果unique()并不总是与相同Series.cat.categories,因为Series.unique()有两个保证,即,它按出现的顺序返回类别,并且仅包括实际存在的值。

    In [63]: s = pd.Series(list("babc")).astype(CategoricalDtype(list("abcd")))
    
    In [64]: s
    Out[64]: 
    0    b
    1    a
    2    b
    3    c
    dtype: category
    Categories (4, object): ['a', 'b', 'c', 'd']
    
    # categories
    In [65]: s.cat.categories
    Out[65]: Index(['a', 'b', 'c', 'd'], dtype='object')
    
    # uniques
    In [66]: s.unique()
    Out[66]: 
    ['b', 'a', 'c']
    Categories (3, object): ['b', 'a', 'c']
    

    重命名类别

    重命名类别是通过为Series.cat.categories属性分配新值 或使用以下 rename_categories()方法来完成的:

    In [67]: s = pd.Series(["a", "b", "c", "a"], dtype="category")
    
    In [68]: s
    Out[68]: 
    0    a
    1    b
    2    c
    3    a
    dtype: category
    Categories (3, object): ['a', 'b', 'c']
    
    In [69]: s.cat.categories = ["Group %s" % g for g in s.cat.categories]
    
    In [70]: s
    Out[70]: 
    0    Group a
    1    Group b
    2    Group c
    3    Group a
    dtype: category
    Categories (3, object): ['Group a', 'Group b', 'Group c']
    
    In [71]: s = s.cat.rename_categories([1, 2, 3])
    
    In [72]: s
    Out[72]: 
    0    1
    1    2
    2    3
    3    1
    dtype: category
    Categories (3, int64): [1, 2, 3]
    
    # You can also pass a dict-like object to map the renaming
    In [73]: s = s.cat.rename_categories({1: "x", 2: "y", 3: "z"})
    
    In [74]: s
    Out[74]: 
    0    x
    1    y
    2    z
    3    x
    dtype: category
    Categories (3, object): ['x', 'y', 'z']
    

    注意

    与R相比factor,类别数据可以具有除字符串以外的其他类型的类别。

    注意

    请注意,分配新类别是一个就地操作,而在Series.cat默认情况下,大多数其他操作都会返回Seriesdtype的新category

    类别必须唯一或ValueError引发:

    In [75]: try:
       ....:     s.cat.categories = [1, 1, 1]
       ....: except ValueError as e:
       ....:     print("ValueError:", str(e))
       ....: 
    ValueError: Categorical categories must be unique
    

    类别也不能为NaNValueError引发:

    In [76]: try:
       ....:     s.cat.categories = [1, 2, np.nan]
       ....: except ValueError as e:
       ....:     print("ValueError:", str(e))
       ....: 
    ValueError: Categorical categories cannot be null
    

    追加新的类别

    可以使用以下add_categories()方法完成附加类别 

    In [77]: s = s.cat.add_categories([4])
    
    In [78]: s.cat.categories
    Out[78]: Index(['x', 'y', 'z', 4], dtype='object')
    
    In [79]: s
    Out[79]: 
    0    x
    1    y
    2    z
    3    x
    dtype: category
    Categories (4, object): ['x', 'y', 'z', 4]
    

    删除类别

    删除类别可以通过使用remove_categories()方法来完成 删除的值将替换为np.nan。:

    In [80]: s = s.cat.remove_categories([4])
    
    In [81]: s
    Out[81]: 
    0    x
    1    y
    2    z
    3    x
    dtype: category
    Categories (3, object): ['x', 'y', 'z']
    

    Removing unused categories

    Removing unused categories can also be done:

    In [82]: s = pd.Series(pd.Categorical(["a", "b", "a"], categories=["a", "b", "c", "d"]))
    
    In [83]: s
    Out[83]: 
    0    a
    1    b
    2    a
    dtype: category
    Categories (4, object): ['a', 'b', 'c', 'd']
    
    In [84]: s.cat.remove_unused_categories()
    Out[84]: 
    0    a
    1    b
    2    a
    dtype: category
    Categories (2, object): ['a', 'b']
    

    Setting categories

    If you want to do remove and add new categories in one step (which has some speed advantage), or simply set the categories to a predefined scale, use set_categories().

    In [85]: s = pd.Series(["one", "two", "four", "-"], dtype="category")
    
    In [86]: s
    Out[86]: 
    0     one
    1     two
    2    four
    3       -
    dtype: category
    Categories (4, object): ['-', 'four', 'one', 'two']
    
    In [87]: s = s.cat.set_categories(["one", "two", "three", "four"])
    
    In [88]: s
    Out[88]: 
    0     one
    1     two
    2    four
    3     NaN
    dtype: category
    Categories (4, object): ['one', 'two', 'three', 'four']
    

    Note

    Be aware that Categorical.set_categories() cannot know whether some category is omitted intentionally or because it is misspelled or (under Python3) due to a type difference (e.g., NumPy S1 dtype and Python strings). This can result in surprising behaviour!

    Sorting and order

    If categorical data is ordered (s.cat.ordered == True), then the order of the categories has a meaning and certain operations are possible. If the categorical is unordered, .min()/.max() will raise a TypeError.

    In [89]: s = pd.Series(pd.Categorical(["a", "b", "c", "a"], ordered=False))
    
    In [90]: s.sort_values(inplace=True)
    
    In [91]: s = pd.Series(["a", "b", "c", "a"]).astype(CategoricalDtype(ordered=True))
    
    In [92]: s.sort_values(inplace=True)
    
    In [93]: s
    Out[93]: 
    0    a
    3    a
    1    b
    2    c
    dtype: category
    Categories (3, object): ['a' < 'b' < 'c']
    
    In [94]: s.min(), s.max()
    Out[94]: ('a', 'c')
    

    您可以将分类数据设置为使用as_ordered()排序或使用排序as_unordered()这些默认情况下将返回一个对象。

    In [95]: s.cat.as_ordered()
    Out[95]: 
    0    a
    3    a
    1    b
    2    c
    dtype: category
    Categories (3, object): ['a' < 'b' < 'c']
    
    In [96]: s.cat.as_unordered()
    Out[96]: 
    0    a
    3    a
    1    b
    2    c
    dtype: category
    Categories (3, object): ['a', 'b', 'c']
    

    排序将使用由类别定义的顺序,而不是数据类型上出现的任何词汇顺序。甚至对于字符串和数字数据也是如此:

    In [97]: s = pd.Series([1, 2, 3, 1], dtype="category")
    
    In [98]: s = s.cat.set_categories([2, 3, 1], ordered=True)
    
    In [99]: s
    Out[99]: 
    0    1
    1    2
    2    3
    3    1
    dtype: category
    Categories (3, int64): [2 < 3 < 1]
    
    In [100]: s.sort_values(inplace=True)
    
    In [101]: s
    Out[101]: 
    1    2
    2    3
    0    1
    3    1
    dtype: category
    Categories (3, int64): [2 < 3 < 1]
    
    In [102]: s.min(), s.max()
    Out[102]: (2, 1)
    

    重新排序

    通过Categorical.reorder_categories()Categorical.set_categories()方法可以重新排序类别对于Categorical.reorder_categories(),所有旧类别都必须包含在新类别中,并且不允许新类别。这将必然使排序顺序与类别顺序相同。

    In [103]: s = pd.Series([1, 2, 3, 1], dtype="category")
    
    In [104]: s = s.cat.reorder_categories([2, 3, 1], ordered=True)
    
    In [105]: s
    Out[105]: 
    0    1
    1    2
    2    3
    3    1
    dtype: category
    Categories (3, int64): [2 < 3 < 1]
    
    In [106]: s.sort_values(inplace=True)
    
    In [107]: s
    Out[107]: 
    1    2
    2    3
    0    1
    3    1
    dtype: category
    Categories (3, int64): [2 < 3 < 1]
    
    In [108]: s.min(), s.max()
    Out[108]: (2, 1)
    

    注意

    请注意分配新类别和对类别重新排序之间的区别:第一个重命名类别,因此重命名了类别中的各个值Series,但是如果第一个位置排在最后,则重命名的值仍将排在最后。重新排序意味着之后对值进行排序的方式有所不同,但不会Series改变值 

    注意

    如果Categorical不订购,Series.min()Series.max()会提高 TypeError数字操作,例如+-*/和基于它们的操作(例如Series.median(),这将需要计算两个值之间的平均值,如果一个数组的长度为偶数)不工作,养TypeError

    多列排序

    dtyped分类列将以与其他列类似的方式参与多列排序。类别的排序由该categories列的确定

    In [109]: dfs = pd.DataFrame(
       .....:     {
       .....:         "A": pd.Categorical(
       .....:             list("bbeebbaa"),
       .....:             categories=["e", "a", "b"],
       .....:             ordered=True,
       .....:         ),
       .....:         "B": [1, 2, 1, 2, 2, 1, 2, 1],
       .....:     }
       .....: )
       .....: 
    
    In [110]: dfs.sort_values(by=["A", "B"])
    Out[110]: 
       A  B
    2  e  1
    3  e  2
    7  a  1
    6  a  2
    0  b  1
    5  b  1
    1  b  2
    4  b  2
    

    重新categories排列更改,以便将来排序。

    In [111]: dfs["A"] = dfs["A"].cat.reorder_categories(["a", "b", "e"])
    
    In [112]: dfs.sort_values(by=["A", "B"])
    Out[112]: 
       A  B
    7  a  1
    6  a  2
    0  b  1
    5  b  1
    1  b  2
    4  b  2
    2  e  1
    3  e  2
    

    比较

    在三种情况下,可以将分类数据与其他对象进行比较:

    • 将相等性(==!=)与长度与分类数据相同的类似列表的对象(列表,序列,数组等)进行比较。

    • 所有的比较(==!=>>=<,和<=分类数据)到另一个分类系列,当ordered==Truecategories是相同的。

    • 分类数据与标量的所有比较。

    所有其他比较,特别是两个具有不同类别的分类或与任何类似列表的对象的分类的“非相等”比较,都会引发TypeError

    注意

    任何“非平等”分类数据的一个比较Seriesnp.arraylist或者与不同类别或排序分类数据将引发TypeError因为自定义类别排序可以通过两种方式来解释:一种是考虑到订货,一个没有。

    In [113]: cat = pd.Series([1, 2, 3]).astype(CategoricalDtype([3, 2, 1], ordered=True))
    
    In [114]: cat_base = pd.Series([2, 2, 2]).astype(CategoricalDtype([3, 2, 1], ordered=True))
    
    In [115]: cat_base2 = pd.Series([2, 2, 2]).astype(CategoricalDtype(ordered=True))
    
    In [116]: cat
    Out[116]: 
    0    1
    1    2
    2    3
    dtype: category
    Categories (3, int64): [3 < 2 < 1]
    
    In [117]: cat_base
    Out[117]: 
    0    2
    1    2
    2    2
    dtype: category
    Categories (3, int64): [3 < 2 < 1]
    
    In [118]: cat_base2
    Out[118]: 
    0    2
    1    2
    2    2
    dtype: category
    Categories (1, int64): [2]
    

    与具有相同类别和顺序的分类比较或与标量比较:

    In [119]: cat > cat_base
    Out[119]: 
    0     True
    1    False
    2    False
    dtype: bool
    
    In [120]: cat > 2
    Out[120]: 
    0     True
    1    False
    2    False
    dtype: bool
    

    相等比较可用于具有相同长度和标量的任何类似列表的对象:

    In [121]: cat == cat_base
    Out[121]: 
    0    False
    1     True
    2    False
    dtype: bool
    
    In [122]: cat == np.array([1, 2, 3])
    Out[122]: 
    0    True
    1    True
    2    True
    dtype: bool
    
    In [123]: cat == 2
    Out[123]: 
    0    False
    1     True
    2    False
    dtype: bool
    

    这是行不通的,因为类别不相同:

    In [124]: try:
       .....:     cat > cat_base2
       .....: except TypeError as e:
       .....:     print("TypeError:", str(e))
       .....: 
    TypeError: Categoricals can only be compared if 'categories' are the same.
    

    如果要对分类序列与不是分类数据的类似列表的对象进行“非相等”比较,则需要明确,并将分类数据转换回原始值:

    In [125]: base = np.array([1, 2, 3])
    
    In [126]: try:
       .....:     cat > base
       .....: except TypeError as e:
       .....:     print("TypeError:", str(e))
       .....: 
    TypeError: Cannot compare a Categorical for op __gt__ with type <class 'numpy.ndarray'>.
    If you want to compare values, use 'np.asarray(cat) <op> other'.
    
    In [127]: np.asarray(cat) > base
    Out[127]: array([False, False, False])
    

    当您比较两个具有相同类别的无序分类时,不考虑该顺序:

    In [128]: c1 = pd.Categorical(["a", "b"], categories=["a", "b"], ordered=False)
    
    In [129]: c2 = pd.Categorical(["a", "b"], categories=["b", "a"], ordered=False)
    
    In [130]: c1 == c2
    Out[130]: array([ True,  True])
    

    操作

    和和之外Series.min()分类数据还可以进行以下操作:Series.max()Series.mode()

    Series像这样的方法Series.value_counts()将使用所有类别,即使数据中不存在某些类别:

    In [131]: s = pd.Series(pd.Categorical(["a", "b", "c", "c"], categories=["c", "a", "b", "d"]))
    
    In [132]: s.value_counts()
    Out[132]: 
    c    2
    a    1
    b    1
    d    0
    dtype: int64
    

    DataFrame类似的方法DataFrame.sum()也显示“未使用”的类别。

    In [133]: columns = pd.Categorical(
       .....:     ["One", "One", "Two"], categories=["One", "Two", "Three"], ordered=True
       .....: )
       .....: 
    
    In [134]: df = pd.DataFrame(
       .....:     data=[[1, 2, 3], [4, 5, 6]],
       .....:     columns=pd.MultiIndex.from_arrays([["A", "B", "B"], columns]),
       .....: )
       .....: 
    
    In [135]: df.sum(axis=1, level=1)
    Out[135]: 
       One  Two  Three
    0    3    3      0
    1    9    6      0
    

    Groupby还将显示“未使用”类别:

    In [136]: cats = pd.Categorical(
       .....:     ["a", "b", "b", "b", "c", "c", "c"], categories=["a", "b", "c", "d"]
       .....: )
       .....: 
    
    In [137]: df = pd.DataFrame({"cats": cats, "values": [1, 2, 2, 2, 3, 4, 5]})
    
    In [138]: df.groupby("cats").mean()
    Out[138]: 
          values
    cats        
    a        1.0
    b        2.0
    c        4.0
    d        NaN
    
    In [139]: cats2 = pd.Categorical(["a", "a", "b", "b"], categories=["a", "b", "c"])
    
    In [140]: df2 = pd.DataFrame(
       .....:     {
       .....:         "cats": cats2,
       .....:         "B": ["c", "d", "c", "d"],
       .....:         "values": [1, 2, 3, 4],
       .....:     }
       .....: )
       .....: 
    
    In [141]: df2.groupby(["cats", "B"]).mean()
    Out[141]: 
            values
    cats B        
    a    c     1.0
         d     2.0
    b    c     3.0
         d     4.0
    c    c     NaN
         d     NaN
    

    数据透视表:

    In [142]: raw_cat = pd.Categorical(["a", "a", "b", "b"], categories=["a", "b", "c"])
    
    In [143]: df = pd.DataFrame({"A": raw_cat, "B": ["c", "d", "c", "d"], "values": [1, 2, 3, 4]})
    
    In [144]: pd.pivot_table(df, values="values", index=["A", "B"])
    Out[144]: 
         values
    A B        
    a c       1
      d       2
    b c       3
      d       4
    

    数据改写(munging)

    优化的Pandas数据访问方法 .loc.iloc.at,和.iat,工作正常。唯一的区别是返回类型(用于获取),并且只能categories分配已经存在的值

    取得

    如果切片操作返回或者是DataFrame或类型的列 Series中,categoryD型细胞被保留。

    In [145]: idx = pd.Index(["h", "i", "j", "k", "l", "m", "n"])
    
    In [146]: cats = pd.Series(["a", "b", "b", "b", "c", "c", "c"], dtype="category", index=idx)
    
    In [147]: values = [1, 2, 2, 2, 3, 4, 5]
    
    In [148]: df = pd.DataFrame({"cats": cats, "values": values}, index=idx)
    
    In [149]: df.iloc[2:4, :]
    Out[149]: 
      cats  values
    j    b       2
    k    b       2
    
    In [150]: df.iloc[2:4, :].dtypes
    Out[150]: 
    cats      category
    values       int64
    dtype: object
    
    In [151]: df.loc["h":"j", "cats"]
    Out[151]: 
    h    a
    i    b
    j    b
    Name: cats, dtype: category
    Categories (3, object): ['a', 'b', 'c']
    
    In [152]: df[df["cats"] == "b"]
    Out[152]: 
      cats  values
    i    b       2
    j    b       2
    k    b       2
    

    不保留类别类型的示例是,如果您只一行,则结果Series为dtype object

    # get the complete "h" row as a Series
    In [153]: df.loc["h", :]
    Out[153]: 
    cats      a
    values    1
    Name: h, dtype: object
    

    从分类数据返回单个项目也将返回值,而不是长度为“ 1”的分类。

    In [154]: df.iat[0, 0]
    Out[154]: 'a'
    
    In [155]: df["cats"].cat.categories = ["x", "y", "z"]
    
    In [156]: df.at["h", "cats"]  # returns a string
    Out[156]: 'x'
    

    注意

    相对于Rfactor函数,后者factor(c(1,2,3))[1] 返回一个值factor

    要获取Seriestype的单个值category,请传入具有单个值的列表:

    In [157]: df.loc[["h"], "cats"]
    Out[157]: 
    h    x
    Name: cats, dtype: category
    Categories (3, object): ['x', 'y', 'z']
    

    字符串和日期时间访问器

    如果访问类型为,访问器 .dt.str将起作用s.cat.categories

    In [158]: str_s = pd.Series(list("aabb"))
    
    In [159]: str_cat = str_s.astype("category")
    
    In [160]: str_cat
    Out[160]: 
    0    a
    1    a
    2    b
    3    b
    dtype: category
    Categories (2, object): ['a', 'b']
    
    In [161]: str_cat.str.contains("a")
    Out[161]: 
    0     True
    1     True
    2    False
    3    False
    dtype: bool
    
    In [162]: date_s = pd.Series(pd.date_range("1/1/2015", periods=5))
    
    In [163]: date_cat = date_s.astype("category")
    
    In [164]: date_cat
    Out[164]: 
    0   2015-01-01
    1   2015-01-02
    2   2015-01-03
    3   2015-01-04
    4   2015-01-05
    dtype: category
    Categories (5, datetime64[ns]): [2015-01-01, 2015-01-02, 2015-01-03, 2015-01-04, 2015-01-05]
    
    In [165]: date_cat.dt.day
    Out[165]: 
    0    1
    1    2
    2    3
    3    4
    4    5
    dtype: int64
    

    注意

    返回的Series(或DataFrame)类型与您该类型的a使用 .str.<method>/的类型相同(而不是类型!)。.dt.<method>Seriescategory

    这意味着,从a的访问器上的 Series方法和属性返回的值与从此方法Series转换为类型之一的访问器上的方法和属性返回的值 category将相等:

    In [166]: ret_s = str_s.str.contains("a")
    
    In [167]: ret_cat = str_cat.str.contains("a")
    
    In [168]: ret_s.dtype == ret_cat.dtype
    Out[168]: True
    
    In [169]: ret_s == ret_cat
    Out[169]: 
    0    True
    1    True
    2    True
    3    True
    dtype: bool
    

    注意

    在上完成了工作categories,然后Series构造了新的。如果您有一个Series类型字符串,其中重复了许多元素(例如中的唯一元素的数量Series比的长度小很多),则这对性能有影响Series在这种情况下,将原件转换Series 为typecategory和use.str.<method>.dt.<property>on其中之一会更快

    设置

    Series只要在以下类别列中设置值即可categories

    In [170]: idx = pd.Index(["h", "i", "j", "k", "l", "m", "n"])
    
    In [171]: cats = pd.Categorical(["a", "a", "a", "a", "a", "a", "a"], categories=["a", "b"])
    
    In [172]: values = [1, 1, 1, 1, 1, 1, 1]
    
    In [173]: df = pd.DataFrame({"cats": cats, "values": values}, index=idx)
    
    In [174]: df.iloc[2:4, :] = [["b", 2], ["b", 2]]
    
    In [175]: df
    Out[175]: 
      cats  values
    h    a       1
    i    a       1
    j    b       2
    k    b       2
    l    a       1
    m    a       1
    n    a       1
    
    In [176]: try:
       .....:     df.iloc[2:4, :] = [["c", 3], ["c", 3]]
       .....: except ValueError as e:
       .....:     print("ValueError:", str(e))
       .....: 
    ValueError: Cannot setitem on a Categorical with a new category, set the categories first
    

    通过分配分类数据设置值还将检查是否categories匹配:

    In [177]: df.loc["j":"k", "cats"] = pd.Categorical(["a", "a"], categories=["a", "b"])
    
    In [178]: df
    Out[178]: 
      cats  values
    h    a       1
    i    a       1
    j    a       2
    k    a       2
    l    a       1
    m    a       1
    n    a       1
    
    In [179]: try:
       .....:     df.loc["j":"k", "cats"] = pd.Categorical(["b", "b"], categories=["a", "b", "c"])
       .....: except ValueError as e:
       .....:     print("ValueError:", str(e))
       .....: 
    ValueError: Cannot set a Categorical with another, without identical categories
    

    将a分配Categorical给其他类型的列的一部分将使用以下值:

    In [180]: df = pd.DataFrame({"a": [1, 1, 1, 1, 1], "b": ["a", "a", "a", "a", "a"]})
    
    In [181]: df.loc[1:2, "a"] = pd.Categorical(["b", "b"], categories=["a", "b"])
    
    In [182]: df.loc[2:3, "b"] = pd.Categorical(["b", "b"], categories=["a", "b"])
    
    In [183]: df
    Out[183]: 
       a  b
    0  1  a
    1  b  a
    2  b  b
    3  1  b
    4  1  a
    
    In [184]: df.dtypes
    Out[184]: 
    a    object
    b    object
    dtype: object
    

    合并/串联

    默认情况下,组合SeriesDataFrames包含相同类别的结果将导致categorydtype,否则结果将取决于基础类别的dtype。导致非分类dtypes的合并可能会具有更高的内存使用率。使用.astype或 union_categoricals确保category结果。

    In [185]: from pandas.api.types import union_categoricals
    
    # same categories
    In [186]: s1 = pd.Series(["a", "b"], dtype="category")
    
    In [187]: s2 = pd.Series(["a", "b", "a"], dtype="category")
    
    In [188]: pd.concat([s1, s2])
    Out[188]: 
    0    a
    1    b
    0    a
    1    b
    2    a
    dtype: category
    Categories (2, object): ['a', 'b']
    
    # different categories
    In [189]: s3 = pd.Series(["b", "c"], dtype="category")
    
    In [190]: pd.concat([s1, s3])
    Out[190]: 
    0    a
    1    b
    0    b
    1    c
    dtype: object
    
    # Output dtype is inferred based on categories values
    In [191]: int_cats = pd.Series([1, 2], dtype="category")
    
    In [192]: float_cats = pd.Series([3.0, 4.0], dtype="category")
    
    In [193]: pd.concat([int_cats, float_cats])
    Out[193]: 
    0    1.0
    1    2.0
    0    3.0
    1    4.0
    dtype: float64
    
    In [194]: pd.concat([s1, s3]).astype("category")
    Out[194]: 
    0    a
    1    b
    0    b
    1    c
    dtype: category
    Categories (3, object): ['a', 'b', 'c']
    
    In [195]: union_categoricals([s1.array, s3.array])
    Out[195]: 
    ['a', 'b', 'b', 'c']
    Categories (3, object): ['a', 'b', 'c']
    

    下表总结了合并的结果Categoricals

    arg1

    arg2

    相同

    结果

    类别

    类别

    真正

    类别

    类别(对象)

    类别(对象)

    对象(推断出dtype)

    类别(整数)

    类别(浮动)

    浮点数(推断出dtype)

    另请参阅关于合并dtype的部分,获取有关保留合并dtype和性能的说明。

    联盟

    如果要合并不一定具有相同类别的分类,则该union_categoricals()函数将合并类似列表的分类。新类别将是被合并类别的并集。

    In [196]: from pandas.api.types import union_categoricals
    
    In [197]: a = pd.Categorical(["b", "c"])
    
    In [198]: b = pd.Categorical(["a", "b"])
    
    In [199]: union_categoricals([a, b])
    Out[199]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['b', 'c', 'a']
    

    默认情况下,结果类别将按其在数据中的显示顺序进行排序。如果要按类别对类别进行分类,请使用sort_categories=True参数。

    In [200]: union_categoricals([a, b], sort_categories=True)
    Out[200]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['a', 'b', 'c']
    

    union_categoricals也可以将两个相同类别的类别和订单信息(例如,您也可以append使用)组合在一起的“简单”案例

    In [201]: a = pd.Categorical(["a", "b"], ordered=True)
    
    In [202]: b = pd.Categorical(["a", "b", "a"], ordered=True)
    
    In [203]: union_categoricals([a, b])
    Out[203]: 
    ['a', 'b', 'a', 'b', 'a']
    Categories (2, object): ['a' < 'b']
    

    出现以下内容TypeError是因为类别是有序的并且不相同。

    In [1]: a = pd.Categorical(["a", "b"], ordered=True)
    In [2]: b = pd.Categorical(["a", "b", "c"], ordered=True)
    In [3]: union_categoricals([a, b])
    Out[3]:
    TypeError: to union ordered Categoricals, all categories must be the same
    

    可以通过使用ignore_ordered=True参数来组合具有不同类别或顺序的有序分类

    In [204]: a = pd.Categorical(["a", "b", "c"], ordered=True)
    
    In [205]: b = pd.Categorical(["c", "b", "a"], ordered=True)
    
    In [206]: union_categoricals([a, b], ignore_order=True)
    Out[206]: 
    ['a', 'b', 'c', 'c', 'b', 'a']
    Categories (3, object): ['a', 'b', 'c']
    

    union_categoricals()也可用于 CategoricalIndexSeries包含分类数据,但请注意,结果数组将始终是纯格式Categorical

    In [207]: a = pd.Series(["b", "c"], dtype="category")
    
    In [208]: b = pd.Series(["a", "b"], dtype="category")
    
    In [209]: union_categoricals([a, b])
    Out[209]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['b', 'c', 'a']
    

    注意

    union_categoricals合并类别时可能会重新编码类别的整数代码。这可能是您想要的,但是如果您依靠类别的确切编号,请注意。

    In [210]: c1 = pd.Categorical(["b", "c"])
    
    In [211]: c2 = pd.Categorical(["a", "b"])
    
    In [212]: c1
    Out[212]: 
    ['b', 'c']
    Categories (2, object): ['b', 'c']
    
    # "b" is coded to 0
    In [213]: c1.codes
    Out[213]: array([0, 1], dtype=int8)
    
    In [214]: c2
    Out[214]: 
    ['a', 'b']
    Categories (2, object): ['a', 'b']
    
    # "b" is coded to 1
    In [215]: c2.codes
    Out[215]: array([0, 1], dtype=int8)
    
    In [216]: c = union_categoricals([c1, c2])
    
    In [217]: c
    Out[217]: 
    ['b', 'c', 'a', 'b']
    Categories (3, object): ['b', 'c', 'a']
    
    # "b" is coded to 0 throughout, same as c1, different from c2
    In [218]: c.codes
    Out[218]: array([0, 1, 2, 0], dtype=int8)
    

    获得的数据输入/输出

    您可以将包含categorydtypes的数据写入HDFStore请参见此处的示例和注意事项。

    也可以将数据写入Stata格式文件或从中读取数据请参见此处的示例和警告。

    写入CSV文件将转换数据,有效删除有关分类(分类和排序)的所有信息。因此,如果您读回CSV文件,则必须将相关列转换回category并分配正确的类别和类别顺序。

    In [219]: import io
    
    In [220]: s = pd.Series(pd.Categorical(["a", "b", "b", "a", "a", "d"]))
    
    # rename the categories
    In [221]: s.cat.categories = ["very good", "good", "bad"]
    
    # reorder the categories and add missing categories
    In [222]: s = s.cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
    
    In [223]: df = pd.DataFrame({"cats": s, "vals": [1, 2, 3, 4, 5, 6]})
    
    In [224]: csv = io.StringIO()
    
    In [225]: df.to_csv(csv)
    
    In [226]: df2 = pd.read_csv(io.StringIO(csv.getvalue()))
    
    In [227]: df2.dtypes
    Out[227]: 
    Unnamed: 0     int64
    cats          object
    vals           int64
    dtype: object
    
    In [228]: df2["cats"]
    Out[228]: 
    0    very good
    1         good
    2         good
    3    very good
    4    very good
    5          bad
    Name: cats, dtype: object
    
    # Redo the category
    In [229]: df2["cats"] = df2["cats"].astype("category")
    
    In [230]: df2["cats"].cat.set_categories(
       .....:     ["very bad", "bad", "medium", "good", "very good"], inplace=True
       .....: )
       .....: 
    
    In [231]: df2.dtypes
    Out[231]: 
    Unnamed: 0       int64
    cats          category
    vals             int64
    dtype: object
    
    In [232]: df2["cats"]
    Out[232]: 
    0    very good
    1         good
    2         good
    3    very good
    4    very good
    5          bad
    Name: cats, dtype: category
    Categories (5, object): ['very bad', 'bad', 'medium', 'good', 'very good']
    

    使用写入SQL数据库也是如此to_sql

    丢失的数据

    Pandas主要使用该值np.nan表示丢失的数据。默认情况下,它不包括在计算中。请参阅“缺少数据”部分

    缺失值不应仅包含在分类中应包含在类别categoriesvalues相反,可以理解的是,NaN是不同的,并且总是可能的。当使用分类的时codes,缺失值将始终具有的代码-1

    In [233]: s = pd.Series(["a", "b", np.nan, "a"], dtype="category")
    
    # only two categories
    In [234]: s
    Out[234]: 
    0      a
    1      b
    2    NaN
    3      a
    dtype: category
    Categories (2, object): ['a', 'b']
    
    In [235]: s.cat.codes
    Out[235]: 
    0    0
    1    1
    2   -1
    3    0
    dtype: int8
    

    对工作方法与丢失的数据,例如isna()fillna(), dropna(),所有正常工作:

    In [236]: s = pd.Series(["a", "b", np.nan], dtype="category")
    
    In [237]: s
    Out[237]: 
    0      a
    1      b
    2    NaN
    dtype: category
    Categories (2, object): ['a', 'b']
    
    In [238]: pd.isna(s)
    Out[238]: 
    0    False
    1    False
    2     True
    dtype: bool
    
    In [239]: s.fillna("a")
    Out[239]: 
    0    a
    1    b
    2    a
    dtype: category
    Categories (2, object): ['a', 'b']
    

    差异与R的factor

    可以观察到与R的因子函数的以下差异:

    • Rlevels命名为categories

    • Rlevels始终是字符串类型,而categories在pandas中则可以是任何dtype。

    • 在创建时无法指定标签。s.cat.rename_categories(new_labels) 之后使用

    • 与R的factor函数相反,使用分类数据作为唯一输入来创建新的分类系列不会删除未使用的类别,而是会创建一个新的分类系列,该类等于传入的!

    • R允许将遗漏值包含在其levels(Pandascategories)中。pandas不允许NaN分类,但是缺少的值仍可以在中values

    陷阱

    内存使用

    a的内存使用量与Categorical类别数加数据长度成正比。相反,objectdtype是数据长度的常数倍。

    In [240]: s = pd.Series(["foo", "bar"] * 1000)
    
    # object dtype
    In [241]: s.nbytes
    Out[241]: 16000
    
    # category dtype
    In [242]: s.astype("category").nbytes
    Out[242]: 2016
    

    注意

    如果类别的数量接近数据的长度,则Categorical它将使用与等效objectdtype表示几乎相同或更多的内存

    In [243]: s = pd.Series(["foo%04d" % i for i in range(2000)])
    
    # object dtype
    In [244]: s.nbytes
    Out[244]: 16000
    
    # category dtype
    In [245]: s.astype("category").nbytes
    Out[245]: 20000
    

    Categorical不是numpy数组

    当前,分类数据及其基础Categorical实现为Python对象,而不是底层NumPy数组dtype。这导致一些问题。

    NumPy本身不知道新的dtype

    In [246]: try:
       .....:     np.dtype("category")
       .....: except TypeError as e:
       .....:     print("TypeError:", str(e))
       .....: 
    TypeError: data type 'category' not understood
    
    In [247]: dtype = pd.Categorical(["a"]).dtype
    
    In [248]: try:
       .....:     np.dtype(dtype)
       .....: except TypeError as e:
       .....:     print("TypeError:", str(e))
       .....: 
    TypeError: Cannot interpret 'CategoricalDtype(categories=['a'], ordered=False)' as a data type
    

    Dtype比较工作:

    In [249]: dtype == np.str_
    Out[249]: False
    
    In [250]: np.str_ == dtype
    Out[250]: False
    

    要检查系列是否包含分类数据,请使用hasattr(s, 'cat')

    In [251]: hasattr(pd.Series(["a"], dtype="category"), "cat")
    Out[251]: True
    
    In [252]: hasattr(pd.Series(["a"]), "cat")
    Out[252]: False
    

    在aSeries类型上使用NumPy函数category不起作用,因为Categoricals 数字数据也不起作用(即使在.categories数字情况下也是如此)。

    In [253]: s = pd.Series(pd.Categorical([1, 2, 3, 4]))
    
    In [254]: try:
       .....:     np.sum(s)
       .....: except TypeError as e:
       .....:     print("TypeError:", str(e))
       .....: 
    TypeError: 'Categorical' does not implement reduction 'sum'
    

    注意

    如果该功能有效,请在https://github.com/pandas-dev/pandas提交错误

    应用中的

    Pandas目前在apply函数中不保留dtype:如果沿行应用,将获得Seriesof object dtype(与获取行->获取一个元素将返回基本类型相同),并且沿列也将转换为object。NaN值不受影响。您可以fillna在应用函数之前使用来处理缺失值。

    In [255]: df = pd.DataFrame(
       .....:     {
       .....:         "a": [1, 2, 3, 4],
       .....:         "b": ["a", "b", "c", "d"],
       .....:         "cats": pd.Categorical([1, 2, 3, 2]),
       .....:     }
       .....: )
       .....: 
    
    In [256]: df.apply(lambda row: type(row["cats"]), axis=1)
    Out[256]: 
    0    <class 'int'>
    1    <class 'int'>
    2    <class 'int'>
    3    <class 'int'>
    dtype: object
    
    In [257]: df.apply(lambda col: col.dtype, axis=0)
    Out[257]: 
    a          int64
    b         object
    cats    category
    dtype: object
    

    分类索引

    CategoricalIndex是一种索引类型,可用于支持重复项索引。这是一个围绕a的容器,Categorical 并允许有效索引和具有大量重复元素的索引的存储。有关更多详细说明,请参见高级索引文档

    设置索引将创建一个CategoricalIndex

    In [258]: cats = pd.Categorical([1, 2, 3, 4], categories=[4, 2, 3, 1])
    
    In [259]: strings = ["a", "b", "c", "d"]
    
    In [260]: values = [4, 2, 3, 1]
    
    In [261]: df = pd.DataFrame({"strings": strings, "values": values}, index=cats)
    
    In [262]: df.index
    Out[262]: CategoricalIndex([1, 2, 3, 4], categories=[4, 2, 3, 1], ordered=False, dtype='category')
    
    # This now sorts by the categories order
    In [263]: df.sort_index()
    Out[263]: 
      strings  values
    4       d       1
    2       b       2
    3       c       3
    1       a       4
    

    副作用

    Series从a构造aCategorical不会复制输入 Categorical这意味着更改Series遗嘱在大多数情况下会更改原始的Categorical

    In [264]: cat = pd.Categorical([1, 2, 3, 10], categories=[1, 2, 3, 4, 10])
    
    In [265]: s = pd.Series(cat, name="cat")
    
    In [266]: cat
    Out[266]: 
    [1, 2, 3, 10]
    Categories (5, int64): [1, 2, 3, 4, 10]
    
    In [267]: s.iloc[0:2] = 10
    
    In [268]: cat
    Out[268]: 
    [10, 10, 3, 10]
    Categories (5, int64): [1, 2, 3, 4, 10]
    
    In [269]: df = pd.DataFrame(s)
    
    In [270]: df["cat"].cat.categories = [1, 2, 3, 4, 5]
    
    In [271]: cat
    Out[271]: 
    [5, 5, 3, 5]
    Categories (5, int64): [1, 2, 3, 4, 5]
    

    使用copy=True防止这种行为,或根本就没有重用Categoricals

    In [272]: cat = pd.Categorical([1, 2, 3, 10], categories=[1, 2, 3, 4, 10])
    
    In [273]: s = pd.Series(cat, name="cat", copy=True)
    
    In [274]: cat
    Out[274]: 
    [1, 2, 3, 10]
    Categories (5, int64): [1, 2, 3, 4, 10]
    
    In [275]: s.iloc[0:2] = 10
    
    In [276]: cat
    Out[276]: 
    [1, 2, 3, 10]
    Categories (5, int64): [1, 2, 3, 4, 10]
    

    注意

    在某些情况下,当您提供NumPy数组而不是Categorical时,也会发生这种情况:使用int数组(例如np.array([1,2,3,4]))将表现出相同的行为,而使用字符串数组(例如np.array(["a","b","c","a"]))则不会。

  • 相关阅读:
    python-TCP传输模型
    python-锁机制
    python-生产者消费者模式
    python-Lock锁线程同步和互斥
    python-Event事件线程同步和互斥
    python-thread封装类创建线程
    python-fifo管道文件通信
    python-thread多线程
    Sublime一些设置
    gdb的user-define command
  • 原文地址:https://www.cnblogs.com/a00ium/p/14322614.html
Copyright © 2020-2023  润新知