2017-04-06 3 views
0

のは、私はこのようなcsvファイル(実際に私は可能100+異なるサービス以上のものを持っている)があるとしましょう:数のすべての可能な2グラム

user_id, services 
user_1, "s1,s2,s1,s4,s2,s3,s2" 
user_2, "s2,s3,s2,s1,s4" 

を、私は最終的に持っているしたいと思いますこの、可能であればほとんどのpythonとパンダを使用して:

user_id, c12,c21,c13,c31,c14,c42,c23,c32,c14,c43,c34 
user_1, 1,1,0,0,1,1,1,1,0,0,0 
user_2, 0,1,0,0,0,0,1,1,1,0,1 
cij =、私はそれがsequenのためだけでなく、使用できるように理想的 sequence si,sj for each user

の数たい

2のceだけでなく3のシーケンスも返されます。

私がSOで見つけたのはsi sjの全体のカウントですが、このようなカウントはありません。私はまた、nグラムいくつかの点で、ピボットテーブルを必要とする、と推測するが、私はそれを一緒に混在させる方法がわからない:/

ご協力いただきありがとうござい

+0

ITSはいいだろう簡単にコピー+はあなたの問題を解決しようとする人々のためのペーストです:) – Roelant

答えて

1

あなたのデータを再作成(ただし、サービスを分割しました異なる列の列)

import pandas as pd 
df = pd.DataFrame() 
df['user_id'] = [1,2] 
df['s1'] = [0, 1] 
df['s2'] = [1, 1] 
df['s3'] = [1,0] 

はその後、我々は組み合わせることができます。

cols = list(df)[1:] 
for c1, c2 in itertools.permutations(c,2): 
    df[c1+c2] = df[c1] & df[c2] 

3に2を変更することによって、あなたは3グラムの代わりに、nグラムを追加することができます。

編集:

私は今あなたの問題をよく理解しています。以下は、文字列で動作するソリューションです。私たちは、発生をカウントして作成し、我々は柔軟な機能を使うnグラムの場合

import pandas as pd 
df = pd.DataFrame([['user1',"s1,s2,s1,s4,s2,s3,s2"],['user2',"s2,s3,s2,s1,s4"]]) 
df.columns = ['userid','services'] 

(あなたがより高いレベルのnグラムを使用する場合があります示されているように)

def find_ngrams(input_list, n): 
    return zip(*[input_list[i:] for i in range(n)]) 

:まず、いくつかのデータを作成しますデータフレーム:

results = {} 
for idx, row in df.iterrows(): 
    list_of_services = row['services'].split(',') 
    combinations = ['c_{}_{}'.format(c1,c2) for c1, c2 in find_ngrams(list_of_services, 2)] 
    results[row['userid']] = {k: 1 for k in combinations} 

df2.from_dict(results).transpose() 

あなたのおもちゃの例には、それが返されます。

 c_s1_s2 c_s1_s4 c_s2_s1 c_s2_s3 c_s3_s2 c_s4_s2 
user1  1.0  1.0  1.0  1.0  1.0  1.0 
user2  NaN  1.0  1.0  1.0  1.0  NaN 
+0

これは 's1'と' s2'を持っているかどうか(つまり、すべてのものを扱うだけです)、 's1'の後ろに' s1'、 's2'の' s2' 、s1、s4、s2 'である。 – AChampion

+0

問題は、すべてのユーザーが同じ数のサービスを持っているわけではないため、各サービスを含むCSVファイルをデータフレームに変換するときにエラーが発生します。私はそれを明確にするために私の元の投稿を編集する –

+0

私の編集を参照してください:)それは助けて欲しい! – Roelant

1

ちょうどPythonとitertoolsを使用すると、itertools.pairwiseレシピを使用してこれを行うことができます。

import itertools as it 

def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = it.tee(iterable) 
    next(b, None) 
    return zip(a, b) 

あなたがcsv.DictReader()を使用してファイルを読んでいると仮定すると:あなたがデータなら

>>> from collection import Counter 
>>> services = ['s1', 's2', 's3', 's4']  # Total set of services 
>>> combs = list(it.permutations(services, 2)) # All combinations of services 
>>> counts = {row['user_id']: Counter(pairwise(row['services'].split(','))) for row in reader} 
>>> [{user: {p: c[p] for p in combs} for user, c in counts.items()}] 
[{'user_1': {('s1', 's2'): 1, 
    ('s1', 's3'): 0, 
    ('s1', 's4'): 1, 
    ('s2', 's1'): 1, 
    ('s2', 's3'): 1, 
    ('s2', 's4'): 0, 
    ('s3', 's1'): 0, 
    ('s3', 's2'): 1, 
    ('s3', 's4'): 0, 
    ('s4', 's1'): 0, 
    ('s4', 's2'): 1, 
    ('s4', 's3'): 0}, 
    'user_2': {('s1', 's2'): 0, 
    ('s1', 's3'): 0, 
    ('s1', 's4'): 1, 
    ('s2', 's1'): 1, 
    ('s2', 's3'): 1, 
    ('s2', 's4'): 0, 
    ('s3', 's1'): 0, 
    ('s3', 's2'): 1, 
    ('s3', 's4'): 0, 
    ('s4', 's1'): 0, 
    ('s4', 's2'): 0, 
    ('s4', 's3'): 0}}] 
+0

ありがとうございますが、それよりも複雑になると思います。実際にはデータのサンプルを少しだけ書いていましたが(単純化するためにはないかもしれませんが)、実際には100以上のサービスがありますので、ペアワイズのdefのすべての異なる組み合わせを手で行うことはほとんど不可能です:/ さらに、結果を辞書ではなくデータフレームとして持つことはできませんか? –

+0

私は理解していません... 'pairwise()'はあなたが10,1000,10000000のアイテムを提供するリストをすべて通過します。 '(si、sj)'のすべてのカウンターを構成します。データセットに基づく追加の手書きコーディングはありません。 'n-grams'が必要な場合は' pairwise() 'を' nwise() 'にするのはかなり簡単です。 – AChampion

関連する問題