2017-06-16 5 views
2

Ich habe einen Pandas Datenrahmen, die wie folgt aussieht:aus der Liste Variable Spalten in Pandas

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

I 2 Millionen Nutzer hat, die jeweils eine Liste von 100 Produkten. Ich brauche meinen Datenrahmen auf diese Weise zu transformieren:

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

jemand eine „pythonic“, schnelle Art und Weise, dies zu tun? Ich nicht wollen für Schleifen durchlaufen, dauert es zu viel Zeit.

Danke

Antwort

3

Sie mit df['items'].values.tolist() und join rekonstruieren können.
Ich ging in diese Richtung, weil es schneller ist als apply.

Angesichts der Größe Ihrer Daten möchten Sie dies stattdessen.

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 

Wir dies ein wenig Zeit rasieren off mit

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

Zeit

%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 

größere Daten

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

das funktioniert auch :) danke –

+0

@MohamedALANI hast du es auf deine Daten ausprobiert? – piRSquared

+0

Ich habe es auf 200 Zeilen versucht, es funktioniert. Beide Methoden brauchten zu viel Zeit und ich musste gehen. Ich werde das morgen laufen lassen und zurückkommen, um dir die Laufzeit zu erzählen. Btw, ich habe 100 Produkte, nicht 30 –

3

können Sie versuchen:

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

ergeben sollten:

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

Ich hoffe, das hilft.

+0

Danke Abdou! :) –

Verwandte Themen