使用一致的映射跨数据框列分解值
Factorize values across dataframe columns with consistent mappings
如何将 pandas factorize
与存在于两列中的值一起使用?
具体来说,我尝试将两列中存在的值转换为数值,并将相应的因式分解值放入新的列中,使得因式分解与两个输入列 'A' 和 'B'.
现有数据框:
A B
0 a b
1 c a
2 d a
3 e c
4 c b
5 b e
6 e f
期望的输出:
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
我可以使用 factorize
成功地用于一列:
df['A_ID'] = pd.factorize(df.A)[0]
如何使用跨两列的值的一致映射来实现这一点?我是否需要求助于使用自定义 lambda
函数,或者有没有办法使用 factorize
?
来完成此操作
如果您想重复使用因式分解值,这是一种方法。
In [2637]: facts = np.unique(np.unique(df[['A', 'B']]), return_index=True)
In [2638]: mapping = dict(zip(*facts))
In [2639]: df.join(df[['A', 'B']].apply(lambda x: x.map(mapping)).add_suffix('_ID'))
Out[2639]:
A B A_ID B_ID
0 a b 0 1
1 c a 2 0
2 d a 3 0
3 e c 4 2
4 c b 2 1
5 b e 1 4
6 e f 4 5
或者, 使用 replace
In [2640]: df.join(df[['A', 'B']].replace(mapping).add_suffix('_ID'))
Out[2640]:
A B A_ID B_ID
0 a b 0 1
1 c a 2 0
2 d a 3 0
3 e c 4 2
4 c b 2 1
5 b e 1 4
6 e f 4 5
并且,为了保留您的值顺序使用
In [2]: mapping = dict(zip(*pd.factorize(df['A'].append(df['B']).drop_duplicates())[::-1]))
In [2]: mapping
Out[2666]: {'a': 0, 'b': 4, 'c': 1, 'd': 2, 'e': 3, 'f': 5}
In [3]: df.join(df[['A', 'B']].replace(mapping).add_suffix('_ID'))
Out[3]:
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
详情
In [2641]: facts
Out[2641]:
(array(['a', 'b', 'c', 'd', 'e', 'f'], dtype=object),
array([0, 1, 2, 3, 4, 5], dtype=int64))
In [2642]: mapping
Out[2642]: {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5}
让我们将 apply
、add_suffix
与 pd.factorize
和 assign
一起使用:
f = pd.factorize(df.stack().drop_duplicates().sort_index(level=1))
s1 = pd.Series(f[0], index=f[1])
print(df.assign(**df.apply(lambda x: x.map(s1)).add_suffix('_ID')))
输出:
A B A_ID B_ID
0 a b 0 1
1 c a 2 0
2 d a 3 0
3 e c 4 2
4 c b 2 1
5 b e 1 4
更新数据集的输出:
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
pd.factorize
, apply
+ pd.Categorical
:
_, b = pd.factorize(df.values.T.reshape(-1, ))
# or df.values.ravel('F'), as suggested by Zero
r = df.apply(lambda x: pd.Categorical(x, b).codes).add_suffix('_ID')
A_ID B_ID
0 0 4
1 1 0
2 2 0
3 3 1
4 1 4
5 4 3
6 3 5
pd.concat([df, r], 1)
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
如何将 pandas factorize
与存在于两列中的值一起使用?
具体来说,我尝试将两列中存在的值转换为数值,并将相应的因式分解值放入新的列中,使得因式分解与两个输入列 'A' 和 'B'.
现有数据框:
A B
0 a b
1 c a
2 d a
3 e c
4 c b
5 b e
6 e f
期望的输出:
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
我可以使用 factorize
成功地用于一列:
df['A_ID'] = pd.factorize(df.A)[0]
如何使用跨两列的值的一致映射来实现这一点?我是否需要求助于使用自定义 lambda
函数,或者有没有办法使用 factorize
?
如果您想重复使用因式分解值,这是一种方法。
In [2637]: facts = np.unique(np.unique(df[['A', 'B']]), return_index=True)
In [2638]: mapping = dict(zip(*facts))
In [2639]: df.join(df[['A', 'B']].apply(lambda x: x.map(mapping)).add_suffix('_ID'))
Out[2639]:
A B A_ID B_ID
0 a b 0 1
1 c a 2 0
2 d a 3 0
3 e c 4 2
4 c b 2 1
5 b e 1 4
6 e f 4 5
或者, 使用 replace
In [2640]: df.join(df[['A', 'B']].replace(mapping).add_suffix('_ID'))
Out[2640]:
A B A_ID B_ID
0 a b 0 1
1 c a 2 0
2 d a 3 0
3 e c 4 2
4 c b 2 1
5 b e 1 4
6 e f 4 5
并且,为了保留您的值顺序使用
In [2]: mapping = dict(zip(*pd.factorize(df['A'].append(df['B']).drop_duplicates())[::-1]))
In [2]: mapping
Out[2666]: {'a': 0, 'b': 4, 'c': 1, 'd': 2, 'e': 3, 'f': 5}
In [3]: df.join(df[['A', 'B']].replace(mapping).add_suffix('_ID'))
Out[3]:
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
详情
In [2641]: facts
Out[2641]:
(array(['a', 'b', 'c', 'd', 'e', 'f'], dtype=object),
array([0, 1, 2, 3, 4, 5], dtype=int64))
In [2642]: mapping
Out[2642]: {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5}
让我们将 apply
、add_suffix
与 pd.factorize
和 assign
一起使用:
f = pd.factorize(df.stack().drop_duplicates().sort_index(level=1))
s1 = pd.Series(f[0], index=f[1])
print(df.assign(**df.apply(lambda x: x.map(s1)).add_suffix('_ID')))
输出:
A B A_ID B_ID
0 a b 0 1
1 c a 2 0
2 d a 3 0
3 e c 4 2
4 c b 2 1
5 b e 1 4
更新数据集的输出:
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5
pd.factorize
, apply
+ pd.Categorical
:
_, b = pd.factorize(df.values.T.reshape(-1, ))
# or df.values.ravel('F'), as suggested by Zero
r = df.apply(lambda x: pd.Categorical(x, b).codes).add_suffix('_ID')
A_ID B_ID
0 0 4
1 1 0
2 2 0
3 3 1
4 1 4
5 4 3
6 3 5
pd.concat([df, r], 1)
A B A_ID B_ID
0 a b 0 4
1 c a 1 0
2 d a 2 0
3 e c 3 1
4 c b 1 4
5 b e 4 3
6 e f 3 5