2017-06-16 81 views
2

列表變量列我有一個熊貓數據幀,看起來像這樣:從熊貓

user items 
1  ["product1", "product2", "product3"] 
2  ["product5", "product7", "product2"] 
3  ["product1", "product4", "product5"] 

我有各有一個名單100種產品的 2個百萬用戶。 我需要改變我的數據幀是這樣的:

user item_1  item_2  item_3 
1  "product1" "product2" "product3" 
2  "product5" "product7" "product2" 
3  "product1" "product4" "product5" 

有誰有一個「Python化」,快速的方法來做到這一點? 我不想想要通過for循環,它需要太多的時間。

謝謝

回答

3

您可以df['items'].values.tolist()join重建。
我去了這個方向,因爲它比apply快。

考慮到您的數據的大小,您將需要這個。

df.drop('items', 1).join(
    pd.DataFrame(df['items'].values.tolist(), df.index).rename(
     columns=lambda x: 'item_{}'.format(x + 1) 
    ) 
) 

    user item_1 item_2 item_3 
0  1 product1 product2 product3 
1  2 product5 product7 product2 
2  3 product1 product4 product5 

我們可以剃一點時間關閉的這與

items_array = np.array(df['items'].values.tolist()) 
cols = np.core.defchararray.add(
    'item_', np.arange(1, items_array.shape[1] + 1).astype(str) 
) 
pd.DataFrame(
    np.column_stack([df['user'].values, items_array]), 
    columns=np.append('user', cols) 
) 

時序

%timeit df[['user']].join(df['items'].apply(pd.Series).add_prefix('item_')) 
%timeit df.drop('items', 1).join(pd.DataFrame(df['items'].values.tolist(), df.index).rename(columns=lambda x: 'item_{}'.format(x + 1))) 

1000 loops, best of 3: 1.8 ms per loop 
1000 loops, best of 3: 1.34 ms per loop 

%%timeit 
items_array = np.array(df['items'].values.tolist()) 
cols = np.core.defchararray.add(
    'item_', np.arange(1, items_array.shape[1] + 1).astype(str) 
) 
pd.DataFrame(
    np.column_stack([df['user'].values, items_array]), 
    columns=np.append('user', cols) 
) 

10000 loops, best of 3: 188 µs per loop 

更大的數據

n = 20000 
items = ['A%s' % i for i in range(1000)] 
df = pd.DataFrame(dict(
     user=np.arange(n), 
     items=np.random.choice(items, (n, 100)).tolist() 
    )) 

%timeit df[['user']].join(df['items'].apply(pd.Series).add_prefix('item_')) 
%timeit df.drop('items', 1).join(pd.DataFrame(df['items'].values.tolist(), df.index).rename(columns=lambda x: 'item_{}'.format(x + 1))) 

1 loop, best of 3: 3.22 s per loop 
1 loop, best of 3: 492 ms per loop 

%%timeit 
items_array = np.array(df['items'].values.tolist()) 
cols = np.core.defchararray.add(
    'item_', np.arange(1, items_array.shape[1] + 1).astype(str) 
) 
pd.DataFrame(
    np.column_stack([df['user'].values, items_array]), 
    columns=np.append('user', cols) 
) 

1 loop, best of 3: 389 ms per loop 
+0

that works too :)謝謝 –

+0

@MohamedALANI你有沒有試過你的數據? – piRSquared

+0

我嘗試過200行,它的工作原理。兩種方法花費了太多時間,我需要去。我明天就跑這個,回來告訴你跑步時間。順便說一句,我其實有100個產品,而不是30 –

3

你可以試試:

df[['user']].join(df['items'].apply(pd.Series).add_prefix('item_')) 

應該產生:

# user item_0 item_1 item_2 
# 0  1 product1 product2 product3 
# 1  2 product5 product7 product2 
# 2  3 product1 product4 product5 

我希望這有助於。

+0

謝謝阿卜杜! :) –