使用一致的映射对跨数据帧列的值进行分解

时间:2017-10-16 02:02:27

标签: python pandas dataframe categories

如何将pandas factorize与两列中存在的值一起使用?

具体来说,我试图将两列中存在的值转换为数值,并将相应的分解值放入新列中,这样分解与两个输入列“A”和“B”一致。 / p>

现有DataFrame:

     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完成此操作?

3 个答案:

答案 0 :(得分:2)

我们将applyadd_suffixpd.factorizeassign一起使用:

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

答案 1 :(得分:1)

如果你想重复使用因子分析值,这是一种方法。

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}

答案 2 :(得分:1)

pd.factorizeapply + 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