Pandas 转出唯一列
Pandas pivot out unique column
我有一个 pandas 数据框,其中两个数据框的组合我认为是唯一标识符,然后是一个可以具有不同值的列 'C'。因此,同一个唯一标识符可以重复的次数与它具有的不同 'C' 值的数量一样多。
import pandas as pd
data = {'A' : ['000001','000001','000001','000001','000002','000002','000003'],
'B' : ['1A','1A','1C','1D','1A','1A','1D'],
'C' : ['003','012','016','003','020','012','053']}
df = pd.DataFrame(data)
+-------------------+
| A | B | C |
+-------------------+
| 000001 | 1A | 003 |
| 000001 | 1A | 012 |
| 000001 | 1C | 016 |
| 000001 | 1D | 003 |
| 000002 | 1A | 020 |
| 000002 | 1A | 012 |
| 000003 | 1D | 053 |
+-------------------+
我想根据 A、B 对行进行分组,然后转出 C 列并将它们变成虚拟对象。这就是我需要的最终输出:
+----------------------------------------------------+
| A | B | C_003 | C_012 | C_016 | C_020 |C_053 |
+----------------------------------------------------+
| 000001 | 1A | 1 | 1 | 0 | 0 | 0 |
| 000001 | 1C | 0 | 0 | 1 | 0 | 0 |
| 000001 | 1D | 1 | 0 | 0 | 0 | 0 |
| 000002 | 1A | 0 | 1 | 0 | 1 | 0 |
| 000003 | 1D | 0 | 0 | 0 | 0 | 1 |
+----------------------------------------------------+
我在枢轴 table 方面真的很糟糕,但也不确定枢轴 table 是否可以达到我想要的输出。我正在寻找一个超级高效的过程,因为实际数据有更多列作为标识符的一部分(如 A、B)、数千个可能的 C 值和数百万行。有什么想法吗?
pandas.get_dummies
救援。
pd.get_dummies(df.set_index(['A', 'B'])).reset_index()
A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 0 0 0 0
1 000001 1A 0 1 0 0 0
2 000001 1C 0 0 1 0 0
3 000001 1D 1 0 0 0 0
4 000002 1A 0 0 0 1 0
5 000002 1A 0 1 0 0 0
6 000003 1D 0 0 0 0 1
或者……(感谢文提醒)
pd.get_dummies(df.set_index(['A', 'B'])).sum(level=[0, 1]).reset_index()
A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
使用groupby
with size
, reshape by unstack
and filter all values higher as 1
by clip_upper
:
df = (df.groupby(['A','B', 'C'])
.size()
.unstack(fill_value=0)
.add_prefix('C_')
.clip_upper(1)
.reset_index())
print (df)
C A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
你知道我记得我最喜欢的功能吗crosstab
pd.crosstab([df.A,df.B],df.C).reset_index()
Out[70]:
C A B 003 012 016 020 053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
通过使用 str
get_dummies
df.set_index(['A','B']).C.str.get_dummies().add_prefix('C_').sum(level=[0,1]).reset_index()
Out[60]:
A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
我有一个 pandas 数据框,其中两个数据框的组合我认为是唯一标识符,然后是一个可以具有不同值的列 'C'。因此,同一个唯一标识符可以重复的次数与它具有的不同 'C' 值的数量一样多。
import pandas as pd
data = {'A' : ['000001','000001','000001','000001','000002','000002','000003'],
'B' : ['1A','1A','1C','1D','1A','1A','1D'],
'C' : ['003','012','016','003','020','012','053']}
df = pd.DataFrame(data)
+-------------------+
| A | B | C |
+-------------------+
| 000001 | 1A | 003 |
| 000001 | 1A | 012 |
| 000001 | 1C | 016 |
| 000001 | 1D | 003 |
| 000002 | 1A | 020 |
| 000002 | 1A | 012 |
| 000003 | 1D | 053 |
+-------------------+
我想根据 A、B 对行进行分组,然后转出 C 列并将它们变成虚拟对象。这就是我需要的最终输出:
+----------------------------------------------------+
| A | B | C_003 | C_012 | C_016 | C_020 |C_053 |
+----------------------------------------------------+
| 000001 | 1A | 1 | 1 | 0 | 0 | 0 |
| 000001 | 1C | 0 | 0 | 1 | 0 | 0 |
| 000001 | 1D | 1 | 0 | 0 | 0 | 0 |
| 000002 | 1A | 0 | 1 | 0 | 1 | 0 |
| 000003 | 1D | 0 | 0 | 0 | 0 | 1 |
+----------------------------------------------------+
我在枢轴 table 方面真的很糟糕,但也不确定枢轴 table 是否可以达到我想要的输出。我正在寻找一个超级高效的过程,因为实际数据有更多列作为标识符的一部分(如 A、B)、数千个可能的 C 值和数百万行。有什么想法吗?
pandas.get_dummies
救援。
pd.get_dummies(df.set_index(['A', 'B'])).reset_index()
A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 0 0 0 0
1 000001 1A 0 1 0 0 0
2 000001 1C 0 0 1 0 0
3 000001 1D 1 0 0 0 0
4 000002 1A 0 0 0 1 0
5 000002 1A 0 1 0 0 0
6 000003 1D 0 0 0 0 1
或者……(感谢文提醒)
pd.get_dummies(df.set_index(['A', 'B'])).sum(level=[0, 1]).reset_index()
A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
使用groupby
with size
, reshape by unstack
and filter all values higher as 1
by clip_upper
:
df = (df.groupby(['A','B', 'C'])
.size()
.unstack(fill_value=0)
.add_prefix('C_')
.clip_upper(1)
.reset_index())
print (df)
C A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
你知道我记得我最喜欢的功能吗crosstab
pd.crosstab([df.A,df.B],df.C).reset_index()
Out[70]:
C A B 003 012 016 020 053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1
通过使用 str
get_dummies
df.set_index(['A','B']).C.str.get_dummies().add_prefix('C_').sum(level=[0,1]).reset_index()
Out[60]:
A B C_003 C_012 C_016 C_020 C_053
0 000001 1A 1 1 0 0 0
1 000001 1C 0 0 1 0 0
2 000001 1D 1 0 0 0 0
3 000002 1A 0 1 0 1 0
4 000003 1D 0 0 0 0 1