如何从数据帧中提取父节点和后续节点

时间:2016-12-30 11:33:48

标签: python pandas

我正在尝试解决以下问题。有一个数据框df

df = 

ID  GROUP_1   GROUP_2    GROUP_3    GROUP_4
1   AAA       AAA        BBB        CCC
2   CCC       AAA        CCC        BBB
3   DDD       CCC        BBB        CCC
4   ...

我需要提取所有组序列并对其进行计数。输出应该是这个(在方括号中我想要给定父节点的所有可能的后续节点):

result =
AAA, 3, [AAA,BBB,CCC]
BBB, 2, [CCC]
CCC, 3, [AAA,BBB]
DDD, 1, [CCC]

我知道如何计算群组的唯一出现次数如下:

df.filter(regex="^GROUP").stack().reset_index(level=1, drop=True).reset_index().drop_duplicates()[0].value_counts()

它提供如下输出:

AAA 2
BBB 3
CCC 3
DDD 1

但是,我不知道如何在没有重复的情况下提取所有可能的后续节点,并计算这些对的所有出现(包括重复)。

2 个答案:

答案 0 :(得分:2)

获取所有可能的值

>>> df.set_index('ID').stack().reset_index(drop=True)
0     AAA
1     AAA
2     BBB
3     CCC
4     CCC
5     AAA
6     CCC
7     BBB
8     DDD
9     CCC
10    BBB
11    CCC

使用pandas.DataFrame.shift获取所有后续值:

>>> df3 = pd.concat([df2, df2.shift(-1)], axis=1)
>>> df3.columns = ['k', 'v']
>>> df3 = df3[df3['v'].notnull()]
>>> df3 = df3.drop_duplicates()
>>> df3
     k    v
0  AAA  AAA
1  AAA  BBB
2  BBB  CCC
3  CCC  CCC
4  CCC  AAA
5  AAA  CCC
6  CCC  BBB
7  BBB  DDD
8  DDD  CCC

使用GroupBy.apply将值汇总到列表:

>>> df3.groupby('k')['v'].apply(list)
k
AAA    [AAA, BBB, CCC]
BBB         [CCC, DDD]
CCC    [BBB, AAA, CCC]
DDD              [CCC]

或者

>>> df3.groupby('k').apply(lambda x: pd.Series([len(x), list(x['v'])]))
     0                1
k                      
AAA  3  [AAA, BBB, CCC]
BBB  2       [CCC, DDD]
CCC  3  [BBB, AAA, CCC]
DDD  1            [CCC]

答案 1 :(得分:2)

另一个选择:

# melt data frame to long format
long_df = pd.melt(df, id_vars = "ID", value_name="First")

# create a shifted subsequent nodes column
(long_df.assign(Second = long_df.groupby("ID").First.shift(-1))

# aggregation grouped by the first column
 .groupby('First').Second
 .agg({'Count': 'count', 'Second': lambda x: x.dropna().unique().tolist()}))

enter image description here

处理缺失值的变种:

变体1

创建移位列后

dropna(),这将删除包含nan的任何对:

(long_df.assign(Second = long_df.groupby("ID").First.shift(-1)).dropna()
 .groupby('First').Second
 .agg({'Count': 'count', 'Second': lambda x: x.unique().tolist()}))

变体2

在创建移位列之前删除长格式数据框中的缺失值,这会将缺失值之前的非缺失值与缺失值之后的值相连接:

(long_df.dropna().assign(Second = long_df.groupby("ID").First.shift(-1))
 .groupby('First').Second
 .agg({'Count': 'count', 'Second': lambda x: x.unique().tolist()}))