将记录的平面表转换为Pandas

时间:2018-06-10 19:59:23

标签: pandas dataframe group-by pivot-table

我有一个关于对象的平面记录表。对象具有类型(ObjType)并托管在容器(ContainerId)中。记录还有关于对象的一些其他属性。但是,它们目前没有兴趣。所以,基本上,数据看起来像这样:

Id  ObjName XT  ObjType ContainerId
2   name1   x1  A   2
3   name2   x5  B   2
22  name5   x3  D   7
25  name6   x2  E   7
35  name7   x3  G   7
..
..
92  name23  x2  A   17
95  name24  x8  B   17
99  name25  x5  A   21

我要做的是重新转动'这些数据可以进一步分析哪些容器是相似的'通过查看它们在聚合中托管的对象类型。

所以,我希望将上述数据转换为以下表格:

ObjType        A    B    C    D    E    F    G
ContainerId                                   
2            2.0  1.0  1.0  0.0  0.0  0.0  0.0
7            0.0  0.0  0.0  1.0  2.0  1.0  1.0
9            1.0  1.0  0.0  1.0  0.0  0.0  0.0
11           0.0  0.0  0.0  2.0  3.0  1.0  1.0
14           1.0  1.0  0.0  1.0  0.0  0.0  0.0
17           1.0  1.0  0.0  0.0  0.0  0.0  0.0
21           1.0  0.0  0.0  0.0  0.0  0.0  0.0

这就是我目前设法做到这一点(经过许多绊脚石并使用诸如this one等问题的各种提示之后)。我得到了正确的结果,但是,对于Pandas和Python的新手,我觉得我必须走很长的路。 (我已经添加了一些评论来解释这些痛点。)

import pandas as pd
rdf = pd.read_csv('.\\testdata.csv')

#The data in the below group-by is all that is needed but in a re-pivoted format...
rdfg = rdf.groupby('ContainerId').ObjType.value_counts()

#Remove 'ContainerId' and 'ObjType' from the index
#Had to do reset_index in two steps because otherwise there's a conflict with 'ObjType'. 
#That is, just rdfg.reset_index() does not work!
rdx = rdfg.reset_index(level=['ContainerId'])

#Renaming the 'ObjType' column helps get around the conflict so the 2nd reset_index works.
rdx.rename(columns={'ObjType':'Count'}, inplace=True)
cdx = rdx.reset_index()

#After this a simple pivot seems to do it
cdf = cdx.pivot(index='ContainerId', columns='ObjType',values='Count')
#Replacing the NaNs because not all containers have all object types
cdf.fillna(0, inplace=True)

问:有人可以分享其他可以执行此转换的方法吗?

1 个答案:

答案 0 :(得分:1)

这是pd.crosstab的用例。 Docs

e.g。

In [539]: pd.crosstab(df.ContainerId, df.ObjType)
Out[539]: 
ObjType      A  B  D  E  G
ContainerId
2            1  1  0  0  0
7            0  0  1  1  1
17           1  1  0  0  0
21           1  0  0  0  0