将多个类别合并为一个 Pandas
Combine multiple categories into one in Pandas
我有一个数据集,其中有一列包含类别。我想做的是将这些类别组合成新的类别。
我的数据集如下所示(类别列是字符串列),我有 160 个类别。
下面我的例子只显示了四个类别。
Category
ZA-01
ZA-01
ZA-01
ZA-01
XA-01
XA-01
XA-01
XA-01
YA-01
YA-01
YA-01
YA-01
WA-01
WA-01
WA-01
WA-01
我想得到的是下面的(dataframe中行的原始顺序不变,这个很重要)
Category New_Category
ZA-01 A
ZA-01 A
ZA-01 A
ZA-01 A
XA-01 A
XA-01 A
XA-01 A
XA-01 A
YA-01 B
YA-01 B
YA-01 B
YA-01 B
WA-01 B
WA-01 B
WA-01 B
WA-01 B
最简单的方法是使用 if elif 语句,但如果您有 160 个类别,这是一项艰巨的任务,而且很容易出错。
我想 Python 做的是使用 df.[['categories]].unique() 获取唯一类别,它保留数据框中类别的顺序,然后对 Python: 将类别一 (ZA-01) 和类别二 (XA-01) 分组为一个名为 A 的新类别,然后将类别三 (YA-01) 和类别四 (WA-01) 分组为一个名为 B 的新类别,依此类推.
在 Python 中有没有不使用 if elif 语句的方法?
----------------编辑---------------------
如果我有
会怎样
Group Category
A ZA-01
A ZA-01
A ZA-01
A ZA-01
A XA-01
A XA-01
A XA-01
A XA-01
A ZZ-12
A ZX-11
B YA-01
B YA-01
B YA-01
B YA-01
B WA-01
B WA-01
B WA-01
B WA-01
B ZZ-01
B ZZ-99
B ZZ-99
B AA-01
我想在一个组中组合两个类别(所以在 A 中我想组合两个类别的组,在 B 中我想组合两个类别等等)。同样,我想保留原始数据框中的行顺序。
所以我想得到
Group Category New_Category
A ZA-01 1
A ZA-01 1
A ZA-01 1
A ZA-01 1
A XA-01 1
A XA-01 1
A XA-01 1
A XA-01 1
A ZZ-12 2
A ZX-11 2
B YA-01 3
B YA-01 3
B YA-01 3
B YA-01 3
B WA-01 3
B WA-01 3
B WA-01 3
B WA-01 3
B ZZ-01 4
B ZZ-99 4
B ZZ-99 4
B AA-01 5
你可以按照你说的去做 map
:
cats = df.Category.unique()
# define new categories
# replace np.arange(len(cats)) with your category names
# e.g ['A','B']
new_cats = np.repeat(np.arange(len(cats)), 2)[:len(cats)]
s = pd.Series(new_cats, index=cats)
df['New_Cat'] = df['Category'].map(s)
输出:
Category New_Cat
0 ZA-01 0
1 ZA-01 0
2 ZA-01 0
3 ZA-01 0
4 XA-01 0
5 XA-01 0
6 XA-01 0
7 XA-01 0
8 YA-01 1
9 YA-01 1
10 YA-01 1
11 YA-01 1
12 WA-01 1
13 WA-01 1
14 WA-01 1
15 WA-01 1
详情: s
是
ZA-01 0
XA-01 0
YA-01 1
WA-01 1
dtype: int32
修改问题:
你不需要groupby。只需将 factorize
与 Group
和 Category
的元组一起使用
df['New_Category']= (pd.factorize(list(zip(df.Group, df.Category)))[0] // 2) + 1
Out[272]:
Group Category New_Category
0 A ZA-01 1
1 A ZA-01 1
2 A ZA-01 1
3 A ZA-01 1
4 A XA-01 1
5 A XA-01 1
6 A XA-01 1
7 A XA-01 1
8 A ZZ-12 2
9 A ZX-11 2
10 B YA-01 3
11 B YA-01 3
12 B YA-01 3
13 B YA-01 3
14 B WA-01 3
15 B WA-01 3
16 B WA-01 3
17 B WA-01 3
18 B ZZ-01 4
19 B ZZ-99 4
20 B ZZ-99 4
21 B AA-01 5
原文:
使用pd.factorize
和floor div 2
df['new_category'] = pd.factorize(df.Category)[0] // 2
Out[154]:
Category new_category
0 ZA-01 0
1 ZA-01 0
2 ZA-01 0
3 ZA-01 0
4 XA-01 0
5 XA-01 0
6 XA-01 0
7 XA-01 0
8 YA-01 1
9 YA-01 1
10 YA-01 1
11 YA-01 1
12 WA-01 1
13 WA-01 1
14 WA-01 1
15 WA-01 1
完成上述 new_category
后,如果您想映射到您的自定义类别,只需执行这些附加步骤
cats = np.array(['A', 'B'])
df['new_category'] = cats[df['new_category']]
Out[163]:
Category new_category
0 ZA-01 A
1 ZA-01 A
2 ZA-01 A
3 ZA-01 A
4 XA-01 A
5 XA-01 A
6 XA-01 A
7 XA-01 A
8 YA-01 B
9 YA-01 B
10 YA-01 B
11 YA-01 B
12 WA-01 B
13 WA-01 B
14 WA-01 B
15 WA-01 B
添加@piRSquare创建字母类别的方法
from string import ascii_uppercase
from itertools import product
import numpy as np
letters = [*ascii_uppercase]
leading = [''] + letters
cats = np.array([*map(''.join, product(*[leading] * 3, letters))])
或
from string import ascii_uppercase
from itertools import product
cats = np.array([*map(''.join, product(['', *ascii_uppercase], ascii_uppercase))])
cats[df.Category.factorize()[0] // 2]
Out[13]:
array(['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B',
'B', 'B', 'B'], dtype='<U2')
我有一个数据集,其中有一列包含类别。我想做的是将这些类别组合成新的类别。
我的数据集如下所示(类别列是字符串列),我有 160 个类别。
下面我的例子只显示了四个类别。
Category
ZA-01
ZA-01
ZA-01
ZA-01
XA-01
XA-01
XA-01
XA-01
YA-01
YA-01
YA-01
YA-01
WA-01
WA-01
WA-01
WA-01
我想得到的是下面的(dataframe中行的原始顺序不变,这个很重要)
Category New_Category
ZA-01 A
ZA-01 A
ZA-01 A
ZA-01 A
XA-01 A
XA-01 A
XA-01 A
XA-01 A
YA-01 B
YA-01 B
YA-01 B
YA-01 B
WA-01 B
WA-01 B
WA-01 B
WA-01 B
最简单的方法是使用 if elif 语句,但如果您有 160 个类别,这是一项艰巨的任务,而且很容易出错。
我想 Python 做的是使用 df.[['categories]].unique() 获取唯一类别,它保留数据框中类别的顺序,然后对 Python: 将类别一 (ZA-01) 和类别二 (XA-01) 分组为一个名为 A 的新类别,然后将类别三 (YA-01) 和类别四 (WA-01) 分组为一个名为 B 的新类别,依此类推.
在 Python 中有没有不使用 if elif 语句的方法?
----------------编辑---------------------
如果我有
会怎样Group Category
A ZA-01
A ZA-01
A ZA-01
A ZA-01
A XA-01
A XA-01
A XA-01
A XA-01
A ZZ-12
A ZX-11
B YA-01
B YA-01
B YA-01
B YA-01
B WA-01
B WA-01
B WA-01
B WA-01
B ZZ-01
B ZZ-99
B ZZ-99
B AA-01
我想在一个组中组合两个类别(所以在 A 中我想组合两个类别的组,在 B 中我想组合两个类别等等)。同样,我想保留原始数据框中的行顺序。
所以我想得到
Group Category New_Category
A ZA-01 1
A ZA-01 1
A ZA-01 1
A ZA-01 1
A XA-01 1
A XA-01 1
A XA-01 1
A XA-01 1
A ZZ-12 2
A ZX-11 2
B YA-01 3
B YA-01 3
B YA-01 3
B YA-01 3
B WA-01 3
B WA-01 3
B WA-01 3
B WA-01 3
B ZZ-01 4
B ZZ-99 4
B ZZ-99 4
B AA-01 5
你可以按照你说的去做 map
:
cats = df.Category.unique()
# define new categories
# replace np.arange(len(cats)) with your category names
# e.g ['A','B']
new_cats = np.repeat(np.arange(len(cats)), 2)[:len(cats)]
s = pd.Series(new_cats, index=cats)
df['New_Cat'] = df['Category'].map(s)
输出:
Category New_Cat
0 ZA-01 0
1 ZA-01 0
2 ZA-01 0
3 ZA-01 0
4 XA-01 0
5 XA-01 0
6 XA-01 0
7 XA-01 0
8 YA-01 1
9 YA-01 1
10 YA-01 1
11 YA-01 1
12 WA-01 1
13 WA-01 1
14 WA-01 1
15 WA-01 1
详情: s
是
ZA-01 0
XA-01 0
YA-01 1
WA-01 1
dtype: int32
修改问题:
你不需要groupby。只需将 factorize
与 Group
和 Category
df['New_Category']= (pd.factorize(list(zip(df.Group, df.Category)))[0] // 2) + 1
Out[272]:
Group Category New_Category
0 A ZA-01 1
1 A ZA-01 1
2 A ZA-01 1
3 A ZA-01 1
4 A XA-01 1
5 A XA-01 1
6 A XA-01 1
7 A XA-01 1
8 A ZZ-12 2
9 A ZX-11 2
10 B YA-01 3
11 B YA-01 3
12 B YA-01 3
13 B YA-01 3
14 B WA-01 3
15 B WA-01 3
16 B WA-01 3
17 B WA-01 3
18 B ZZ-01 4
19 B ZZ-99 4
20 B ZZ-99 4
21 B AA-01 5
原文:
使用pd.factorize
和floor div 2
df['new_category'] = pd.factorize(df.Category)[0] // 2
Out[154]:
Category new_category
0 ZA-01 0
1 ZA-01 0
2 ZA-01 0
3 ZA-01 0
4 XA-01 0
5 XA-01 0
6 XA-01 0
7 XA-01 0
8 YA-01 1
9 YA-01 1
10 YA-01 1
11 YA-01 1
12 WA-01 1
13 WA-01 1
14 WA-01 1
15 WA-01 1
完成上述 new_category
后,如果您想映射到您的自定义类别,只需执行这些附加步骤
cats = np.array(['A', 'B'])
df['new_category'] = cats[df['new_category']]
Out[163]:
Category new_category
0 ZA-01 A
1 ZA-01 A
2 ZA-01 A
3 ZA-01 A
4 XA-01 A
5 XA-01 A
6 XA-01 A
7 XA-01 A
8 YA-01 B
9 YA-01 B
10 YA-01 B
11 YA-01 B
12 WA-01 B
13 WA-01 B
14 WA-01 B
15 WA-01 B
添加@piRSquare创建字母类别的方法
from string import ascii_uppercase
from itertools import product
import numpy as np
letters = [*ascii_uppercase]
leading = [''] + letters
cats = np.array([*map(''.join, product(*[leading] * 3, letters))])
或
from string import ascii_uppercase
from itertools import product
cats = np.array([*map(''.join, product(['', *ascii_uppercase], ascii_uppercase))])
cats[df.Category.factorize()[0] // 2]
Out[13]:
array(['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B',
'B', 'B', 'B'], dtype='<U2')