pandas中category类型的数据处理
pandas中category類型的數(shù)據(jù)
- 用途和特點(diǎn)
- 常見(jiàn)的問(wèn)題處理
- Categorical 數(shù)據(jù)
用途和特點(diǎn)
category是pandas中定義的一個(gè)數(shù)據(jù)類型,相當(dāng)于R中的因子??梢詫?duì)特點(diǎn)的類型數(shù)據(jù)進(jìn)行按照自己的意愿進(jìn)行排序,特別是我們?cè)谔幚頂?shù)據(jù)是需要對(duì)字符串進(jìn)行排序時(shí),有時(shí)候默認(rèn)的順序真的很無(wú)奈。這個(gè)時(shí)候就是這個(gè)類型該入場(chǎng)的時(shí)候了。下面我們看下這個(gè)類型的具體使用情況。
常見(jiàn)的問(wèn)題處理
在日常數(shù)據(jù)處理中使用pd.cut或pd.qcut時(shí),默認(rèn)分組標(biāo)簽就是category類型,不知道你處理時(shí)是否頭疼過(guò)。不過(guò)這個(gè)確實(shí)給我們想向里面加數(shù)據(jù)時(shí)帶來(lái)了麻煩,例如以下情況:
import numpy as np import pandas as pd lst=[np.nan,np.nan] lst.extend(range(1,100)) data=pd.DataFrame({'A':lst ,'B':np.random.randn(101)}) #想把缺失值分成一個(gè)組,先不處理缺失值 data['group']=pd.cut(data['A'],10) #分組后填充缺失值data['group'].fillna('空缺')這樣就會(huì)報(bào)如下錯(cuò)誤:
當(dāng)然了這里你可以把分組標(biāo)簽轉(zhuǎn)成字符串處理,但是會(huì)出現(xiàn)排序不理想的情況。這里可以這樣完美解決。
這個(gè)是為什么?不要急下面就說(shuō)原因。
Categorical 數(shù)據(jù)
這里可以參考文檔:pandas文檔
上面已經(jīng)說(shuō)了,categorical類型是pandas中定義的一個(gè)變量。
1、Series的創(chuàng)建
可以通過(guò)幾種方式創(chuàng)建類別中的類別Series或列DataFrame:
通過(guò)指定dtype="category"在構(gòu)造時(shí)Series:
輸出:
通過(guò)將現(xiàn)有的Series或列轉(zhuǎn)換為categorydtype:
通過(guò)使用特殊功能(例如)cut(),可以將數(shù)據(jù)分組為離散的bin。請(qǐng)參閱文檔中有關(guān)的示例。
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通過(guò)將pandas.Categorical對(duì)象傳遞給Series或?qū)⑵浞峙浣oDataFrame。
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_catIn [15]: df Out[15]: A B 0 a NaN 1 b b 2 c c 3 a NaN2、DataFrame 創(chuàng)建
可以在創(chuàng)建時(shí)dataframe時(shí),定義
3、控制category
通過(guò)上面的例子可能已經(jīng)對(duì)這個(gè)類型有所了解了。下面我們看下它的強(qiáng)大之處。
輸出:
這里,我們定義一個(gè)Categorical類型數(shù)據(jù),沒(méi)有定義在列表的值被置成了NaN值。我們?cè)倏聪陆Y(jié)果中[b < c < a],這個(gè)排序和python默認(rèn)序列已經(jīng)不一樣了。
Categorical類型數(shù)據(jù)我們定義后,是一個(gè)固定的列表了,我們不能直接添加沒(méi)有定義的類別。這里就需要對(duì)類型數(shù)據(jù)進(jìn)行操作了。
3、類型數(shù)據(jù)的基本操作
分類數(shù)據(jù)具有類別和有序?qū)傩?#xff0c;它們列出了它們的可能值以及排序是否重要。這些屬性在s.cat.categories和中公開(kāi)s.cat.ordered。如果您不手動(dòng)指定類別和順序,則可以從傳遞的參數(shù)中推斷出它們。
也可以按特定順序傳遞類別:
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這里注意:新的分類數(shù)據(jù)不會(huì)自動(dòng)排序。您必須明確傳遞ordered=True以指示已定義的Categorical
4、重命名
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]請(qǐng)注意,分配新類別是一個(gè)就地操作,而Series.cat默認(rèn)情況下,大多數(shù)其他操作將返回一個(gè)新Series的dtype category。
這里類別必須是唯一和非NaN值,否知會(huì)報(bào)錯(cuò)
In [75]: try:....: s.cat.categories = [1, 1, 1]....: except ValueError as e:....: print("ValueError:", str(e))....: ValueError: Categorical categories must be unique In [76]: try:....: s.cat.categories = [1, 2, np.nan]....: except ValueError as e:....: print("ValueError:", str(e))....: ValueError: Categorial categories cannot be null5、追加新的類別
可以使用以下.cat.add_categories()方法完成附加類別 :
6、刪除類別
刪除類別可以通過(guò)使用.cat.remove_categories()方法來(lái)完成 。刪除的值將替換為np.nan。
7、刪除未使用的類別
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]8、設(shè)置類別
一步一步的刪除和添加新類別,相對(duì)比較麻煩,可以使用.cat.set_categories來(lái)設(shè)置。
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]```9、排序和順序```python 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')或者使用.cat.as_ordered()排序
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]```這些基本上夠用的了,想了解更深的可以查看[官網(wǎng)資料](https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html)。總結(jié)
以上是生活随笔為你收集整理的pandas中category类型的数据处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何查看路由器外网IP地址
- 下一篇: 汉字字库