2016-12-30 7 views
2

次の問題を解決しようとしています。私はグループのすべてのシーケンスを抽出し、それらをカウントする必要がデータフレームから親ノードと後続ノードを抽出する方法

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 ... 

:データフレームdfがあります。出力は、この1(二乗括弧で私は与えられた親ノードのすべての可能な、後続のノードを持つようにしたい)する必要があります:

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

私は次のようにグループのユニークoccurancesの数をカウントする方法を知っている:

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

それはこの1つのように出力できます。しかし、私は重複せずにすべての可能な、後続のノードを抽出し、これらのペアのすべての回出てくるカウントする方法がわからない

AAA 2 
BBB 3 
CCC 3 
DDD 1 

を(重複を含む)。

+0

DDD、1、[CCC] '行はどのようにして取得できましたか?または 'CCC、3、[AAA、BBB]'行? –

+0

@RomanPekar: 'df'で見ることができるように、' DDD'という値は 'CCC'という1つの可能な次の列の値しか持たず、' 'という行が1つしかありません。'CCC'についても同じです:この値は' AAA'と 'BBB'である次の列の2つの可能な一意の値を持つことができ、' '(行2)、' ' (行2)、「」(行3)。今はっきりしていますか?ありがとう。 – Dinosaurius

答えて

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


Variantions欠損値に対処するための:バリエーション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()})) 
+0

「ファースト」とは何ですか?私の例では 'GROUP_'に対応していますか? – Dinosaurius

+0

私は 'melt'の値の列を' First'に変更しました。これは 'GROUP_'列の値に対応していますが、長い形式です。 – Psidom

+0

'GROUP_X'列に空の値がある場合はどうなりますか?このソリューションは 'SecondN'列の' NaN'をリストに入れますか?それを避ける方法は?申し訳ありませんが、私はこの重要な点については言及していません。 – Dinosaurius

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を使用して、後続のすべての値ゲット:GroupBy.applyを使用してリストへ

>>> 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 

集計値:

>>> 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] 
+0

ニース。しかし、最終結果に入れるために、各親ノードのすべての出現回数をどのように計算すればよいでしょうか? – Dinosaurius

+0

@Dinosaurius更新を参照してください –

+0

あなたのソリューションをありがとう。私はPsidomのソリューションを受け入れました。私のデータセットでは少し速いからです。 – Dinosaurius

関連する問題