Иллюстрация классификации данных в Pandas

Python
Иллюстрация классификации данных в Pandas

Иллюстрация классификации данных в Pandas

В этой статье представлен тип Categorical, который в основном реализует проблему классификации данных, которая используется для переноса целочисленного отображения категории или закодированных данных, чтобы помочь пользователям повысить производительность и использование памяти.

История вопроса: подсчет повторяющихся значений

Повторяющиеся значения часто появляются в данных серии, нам нужно извлечь эти разные значения и рассчитать их частоты отдельно:

import numpy as np
import pandas as pd
data = pd.Series(["语文","数学","英语","数学","英语","地理","语文","语文"])
data
0    语文
1    数学
2    英语
3    数学
4    英语
5    地理
6    语文
7    语文
dtype: object
# 1、提取不同的值

pd.unique(data)
array(['语文', '数学', '英语', '地理'], dtype=object)
# 2、统计每个值的个数

pd.value_counts(data)
语文    3
数学    2
英语    2
地理    1
dtype: int64

Классификация, словарное кодирование

Способ, представленный целыми числами, называется классификацией или словарным кодированием. Различные массивы могут называться категориями, словарями или иерархиями данных.

df = pd.Series([0,1,1,0] * 2)
df
0    0
1    1
2    1
3    0
4    0
5    1
6    1
7    0
dtype: int64
# dim使用维度表

dim = pd.Series(["语文","数学"])
dim
0    语文
1    数学
dtype: object

Как сделать однозначное соответствие между 0-языком и 1-математикой в ​​df? использоватьtakeметод достижения

df1 = dim.take(df)
df1
0    语文
1    数学
1    数学
0    语文
0    语文
1    数学
1    数学
0    语文
dtype: object
type(df1)  # Series数据
pandas.core.series.Series

Создание категориального типа

Сгенерируйте категориальный объект экземпляра

Объясните использование категориальных типов на примерах

subjects = ["语文","数学","语文","语文"] * 2

N = len(subjects)
df2 = pd.DataFrame({
    "subject":subjects,
    "id": np.arange(N),  # 连续整数
    "score":np.random.randint(3,15,size=N),  # 随机整数
    "height":np.random.uniform(165,180,size=N)  # 正态分布的数据
   },
  columns=["id","subject","score","height"])  # 指定列名称的顺序

df2

Вы можете преобразовать тему в категориальный тип:

subject_cat = df2["subject"].astype("category")
subject_cat

Мы обнаружили две характеристики subject_cat:

  • Это не массив numpy, а тип данных категории
  • В нем две ценности: язык и математика
s = subject_cat.values
s
['语文', '数学', '语文', '语文', '语文', '数学', '语文', '语文']
Categories (2, object): ['数学', '语文']
type(s)
pandas.core.arrays.categorical.Categorical
s.categories  # 查看分类
Index(['数学', '语文'], dtype='object')
s.codes  # 查看分类编码
array([1, 0, 1, 1, 1, 0, 1, 1], dtype=int8)

Как генерировать категориальные объекты

Есть в основном два пути:

  • Укажите столбец DataFrame как категориальный объект
  • Сгенерировано pandas.Categorical
  • С помощью конструктора from_codes предполагается, что вы должны сначала получить категориальные закодированные данные
# 方式1

df2["subject"] = df2["subject"].astype("category")
df2.subject
0    语文
1    数学
2    语文
3    语文
4    语文
5    数学
6    语文
7    语文
Name: subject, dtype: category
Categories (2, object): ['数学', '语文']
# 方式2

fruit = pd.Categorical(["苹果","香蕉","葡萄","苹果","苹果","香蕉"])
fruit
['苹果', '香蕉', '葡萄', '苹果', '苹果', '香蕉']
Categories (3, object): ['苹果', '葡萄', '香蕉']
# 方式3

categories = ["height","score","subject"]
codes = [0,1,0,2,1,0]

my_data = pd.Categorical.from_codes(codes, categories)
my_data
['height', 'score', 'height', 'subject', 'score', 'height']
Categories (3, object): ['height', 'score', 'subject']

Преобразование общей классификации не определяет порядок категорий, мы можем указать значимый порядок с помощью упорядоченного параметра:

['height', 'score', 'height', 'subject', 'score', 'height']
Categories (3, object): ['height' < 'score' < 'subject']

вывод вышеheight<socre, что указывает на то, что порядок высоты находится перед счетом. Если экземпляр классификации не упорядочен, мы используем as_ordered для упорядочения:

# my_data未排序

my_data.as_ordered()
['height', 'score', 'height', 'subject', 'score', 'height']
Categories (3, object): ['height' < 'score' < 'subject']

Расчет категориального объекта

Расчеты

np.random.seed(12345)

data1 = np.random.randn(100)
data1[:10]
array([-0.20470766,  0.47894334, -0.51943872, -0.5557303 ,  1.96578057,
        1.39340583,  0.09290788,  0.28174615,  0.76902257,  1.24643474])
# 计算data1的4分位分箱,并提取统计值

bins_1 = pd.qcut(data1,4)
bins_1
[(-0.717, 0.106], (0.106, 0.761], (-0.717, 0.106], (-0.717, 0.106], (0.761, 3.249], ..., (0.761, 3.249], (0.106, 0.761], (-2.371, -0.717], (0.106, 0.761], (0.106, 0.761]]
Length: 100
Categories (4, interval[float64]): [(-2.371, -0.717] < (-0.717, 0.106] < (0.106, 0.761] < (0.761, 3.249]]

Вы можете увидеть значение, возвращаемое вышеприведенным объектом категории результатов.

  • Есть 4 значения
  • Посмотрите, что максимальное и минимальное значения всех данных находятся в начале и в конце соответственно.
# 在上面的4分位数中使用四分位数名称:Q1\Q2\Q3\Q4

bins_2 = pd.qcut(data1,4,labels=["Q1","Q2","Q3","Q4"])
bins_2
['Q2', 'Q3', 'Q2', 'Q2', 'Q4', ..., 'Q4', 'Q3', 'Q1', 'Q3', 'Q3']
Length: 100
Categories (4, object): ['Q1' < 'Q2' < 'Q3' < 'Q4']
bins_2.codes[:10]
array([1, 2, 1, 1, 3, 3, 1, 2, 3, 3], dtype=int8)

Группа статистики для сводной статистики:

bins_2 = pd.Series(bins_2, name="quartile")  # 取名为quartile
bins_2
0     Q2
1     Q3
2     Q2
3     Q2
4     Q4
      ..
95    Q4
96    Q3
97    Q1
98    Q3
99    Q3
Name: quartile, Length: 100, dtype: category
Categories (4, object): ['Q1' < 'Q2' < 'Q3' < 'Q4']

В следующем примере кода данные data1 группируются по bins_2 для создания 3 статистических функций.

results = pd.Series(data1).groupby(bins_2).agg(["count","min","max"]).reset_index()
results

results["quartile"] # quartile列保持的原始分类信息
0    Q1
1    Q2
2    Q3
3    Q4
Name: quartile, dtype: category
Categories (4, object): ['Q1' < 'Q2' < 'Q3' < 'Q4']

Снижение памяти после классификации

N = 10000000  # 千万的数据

data3 = pd.Series(np.random.randn(N))
labels3 = pd.Series(["foo", "bar", "baz", "quz"] * (N // 4))
categories3 = labels3.astype("category")  # 分类转换
# 比较两个的内存

print("data3: ",data3.memory_usage())
print("categories3: ",categories3.memory_usage())
data3:  80000128
categories3:  10000332

Классификация

Доступ к секретной информации

Метод классификации в основном реализуется с помощью специального атрибута cat.

data
0    语文
1    数学
2    英语
3    数学
4    英语
5    地理
6    语文
7    语文
dtype: object
cat_data = data.astype("category")
cat_data  # 分类数据
0    语文
1    数学
2    英语
3    数学
4    英语
5    地理
6    语文
7    语文
dtype: category
Categories (4, object): ['地理', '数学', '英语', '语文']

Добавить категорию

Когда категория фактических данных превышает 4 значения, наблюдаемые в данных:

actual_cat = ["语文","数学","英语","地理","生物"]

cat_data2 = cat_data.cat.set_categories(actual_cat)
cat_data2

«Организм» фигурирует в приведенных выше результатах классификации.

cat_data.value_counts()
语文    3
数学    2
英语    2
地理    1
dtype: int64
cat_data2.value_counts()  # 下面的结果中出现了“生物”
语文    3
数学    2
英语    2
地理    1
生物    0
dtype: int64

удалить категорию

cat_data3 = cat_data[cat_data.isin(["语文","数学"])]  # 只筛选出语文和数学

cat_data3
0    语文
1    数学
3    数学
6    语文
7    语文
dtype: category
Categories (4, object): ['地理', '数学', '英语', '语文']
cat_data3.cat.remove_unused_categories()  # 删除未使用的分类
0    语文
1    数学
3    数学
6    语文
7    语文
dtype: category
Categories (2, object): ['数学', '语文']

Создание фиктивных переменных

Преобразование категориальных данных в фиктивные переменные, то есть однократное кодирование (однократное кодирование); все разные категории в сгенерированном DataFrame являются одним из его столбцов, см. следующий пример:

data4 = pd.Series(["col1","col2","col3","col4"] * 2, dtype="category")
data4
0    col1
1    col2
2    col3
3    col4
4    col1
5    col2
6    col3
7    col4
dtype: category
Categories (4, object): ['col1', 'col2', 'col3', 'col4']
pd.get_dummies(data4)  # get_dummies:将一维的分类数据转换成一个包含虚拟变量的DataFrame

Классификация

  • add_categories: добавить новые категории в хвост
  • as_ordered: порядок категорий
  • as_unordered: сделать категорию неупорядоченной
  • remove_categories: удалить категории, установить для удаленного значения значение null
  • remove_unused_categories: удалить все категории, которые не отображаются
  • rename_categories: заменить название категории без изменения количества категорий
  • reorder_categories: категории для сортировки
  • set_categories: заменить исходный класс указанным набором новых классов, которые можно добавить или удалить.