2016-06-15 9 views
0

入力ログを入力データセットに変換するのはかなり悪い方法です。 私は、次の形式でSFrame平方フィートを持っている:SFramesを入力データセットSframesに変換する

user_id  int 
timestamp datetime.datetime 
action  int 
reasoncode str 

アクション列が占めるので、すべてのUSER_IDは複数回、1つの以上のアクションを実行することができ、1から9

までの9つの値。

私はSFからすべての独特のuser_idを取得し、次のようにop_sfを作成しようとしています:

y = 225 

def calc_class(a,x): 
    diffd = a['timestamp'].apply(lambda x: (dte - x).days) 
    g = 0 
    b = 0 
    for i in diffd: 
    if i > y: 
    g += 1 
    else: 
    b += 1 
    if b>= x: 
    return 4 
    elif b!= 0: 
    return 3 
    elif g>= 0: 
    return 2 
    else: 
    return 1 

l1 = [] 
ids = z['user_id'].unique() 

for idd in ids: 
temp = sf[sf['user_id']== idd] 
zero1 = temp[temp['action'] == 1] 
zero2 = temp[temp['action'] == 2] 
zero3 = temp[temp['action'] == 3] 
zero4 = temp[temp['action'] == 4] 
zero5 = temp[temp['action'] == 5] 
zero6 = temp[temp['action'] == 6] 
zero7 = temp[temp['action'] == 7] 
zeroh8 = temp[temp['reasoncode'] == 'xyz'] 
zero9 = temp[temp['reasoncode'] == 'abc'] 
/* I'm getting clas1 to clas9 from function calc_class for each action 
    clas1 to clas9 are 4 integers ranging from 1 to 4 
*/ 
clas1 = calc_class(zero1,2) 
clas2 = calc_class(zero2,2) 
clas3 = calc_class(zero3,2) 
clas4 = calc_class(zero4,2) 
clas5 = calc_class(zero5,2) 
clas6 = calc_class(zero6,2) 
clas7 = calc_class(zero7,2) 
clas8 = calc_class(zero8,2) 
clas9 = calc_class(zero9,2) 
l1.append([idd,clas1,clas2,clas3,clas4,clas5*(-1),clas6*(-1),clas7*(-1),clas8*(-1),clas9]) 

私は、これがこれを行うための最速の方法かどうかを知りたいと思いました。具体的には、zero1〜zero9 SFramesを生成せずに同じことを実行できるかどうか。

例SF:SF上記に対応する

user_id timestamp action reasoncode 
574 23/09/15 12:43 1 None 
574 23/09/15 11:15 2 None 
574 06/10/15 11:20 2 None 
574 06/10/15 11:21 3 None 
588 04/11/15 10:00 1 None 
588 05/11/15 10:00 1 None 
555 15/12/15 13:00 1 None 
585 22/12/15 17:30 1 None 
585 15/01/16 07:44 7 xyz 
588 06/01/16 08:10 7 abc 

をL1:

574 1 2 2 0 0 0 0 0 0 
588 3 0 0 0 0 0 0 0 3 
555 3 0 0 0 0 0 0 0 0 
585 3 0 0 0 0 0 0 3 0 
+0

、それはあなたが何をしようとしているかを理解するのは難しいです。あなたの目標について少し詳しく説明し、入力と出力のデータの小さな例を表示できますか? – papayawarrior

+1

ここでは複雑なロジックがあるようです。 @papayawarriorが示唆しているように、いくつかのサンプルデータを使った簡単な例があると便利です。しかし、すべての "ゼロ" sframesを生成するロジックから、私はすべての一意のIDをループする理由は見当たりません。おそらく、このロジックを持つ関数でapplyを使用することで、これらのすべてを生成することはできません(たとえば、アクション== 6:x6を使用する、それが7ならx7を使用)。タイムスタンプをSFrame全体に変換することもできます。 –

+0

@EvanSamanasに例を挙げることができますか? –

答えて

1

私はあなたのロジックが比較的複雑であると思うが、上のカラム単位の演算を使用することがより効率的です各ユーザーの行のサブセットを抽出するのではなく、全体のデータセット。主要なツールは、SFrame.groupby,SFrame.apply,SFrame.unstack、およびSFrame.unpackです。ここではAPIドキュメント:

https://dato.com/products/create/docs/generated/graphlab.SFrame.html

ここで古い対新しいアクションをコーディングするためにあなたの例と少しシンプルなロジックよりもややシンプルなデータを使用するソリューションです。このコードスニペットから

# Set up and make the data 
import graphlab as gl 
import datetime as dt 

sf = gl.SFrame({'user': [574, 574, 574, 588, 588, 588], 
       'timestamp': [dt.datetime(2015, 9, 23), dt.datetime(2015, 9, 23), 
           dt.datetime(2015, 10, 6), dt.datetime(2015, 11, 4), 
           dt.datetime(2015, 11, 5), dt.datetime(2016, 1, 6)], 
       'action': [1, 2, 3, 1, 1, 7]}) 

# Count old vs. new actions. 
sf['days_elapsed'] = (dt.datetime.today() - sf['timestamp'])/(3600 * 24) 
sf['old_threshold'] = sf['days_elapsed'] > 225 

aggregator = {'total_count': gl.aggregate.COUNT('user'), 
       'old_count': gl.aggregate.SUM('old_threshold')} 
grp = sf.groupby(['user', 'action'], aggregator) 

# Code the actions according to old vs. new. Use your own logic here. 
grp['action_code'] = grp.apply(
         lambda x: 2 if x['total_count'] > x['old_count'] else 1) 
grp = grp[['user', 'action', 'action_code']] 

# Reshape the results into columns. 
sf_new = (grp.unstack(['action', 'action_code'], new_column_name='action_code') 
      .unpack('action_code')) 

# Fill in zeros for entries with no actions. 
for c in sf_new.column_names(): 
    sf_new[c] = sf_new[c].fillna(0) 

print sf_new 
+------+---------------+---------------+---------------+---------------+ 
| user | action_code.1 | action_code.2 | action_code.3 | action_code.7 | 
+------+---------------+---------------+---------------+---------------+ 
| 588 |  2  |  0  |  0  |  2  | 
| 574 |  1  |  1  |  1  |  0  | 
+------+---------------+---------------+---------------+---------------+ 
[2 rows x 5 columns] 
+0

すごい!私はたくさんのことを学んだ!私はunpack()について全く知らなかった。どうもありがとう –

関連する問題