2017-08-03 65 views

回答

6

使用numpy.concatenate爲flatennig然後numpy.unique

a = np.unique(np.concatenate(df['available_fruits'].values.tolist())).tolist() 
print(a) 

['apple', 'banana', 'kiwi', 'tomato'] 

另一種解決方案是由chain.from_iterable扁平化,獲得獨特的set和最後轉換到list

from itertools import chain 
a = list(set(chain.from_iterable(df.available_fruits.values.tolist()))) 
print(a) 
['tomato', 'kiwi', 'apple', 'banana'] 

時序

df = pd.concat([df]*10000).reset_index(drop=True) 
#print (df) 

In [62]: %timeit list(set(concat(df.available_fruits.values.tolist()))) 
100 loops, best of 3: 3.16 ms per loop 

In [63]: %timeit np.unique(np.concatenate(df['available_fruits'].values.tolist())).tolist() 
10 loops, best of 3: 99.2 ms per loop 

#John Galt's solution 
In [64]: %timeit list(set(df.available_fruits.sum())) 
1 loop, best of 3: 4.12 s per loop 

#pir's solution 0 
In [65]: %timeit list(set(concat(df.available_fruits.values.tolist()))) 
100 loops, best of 3: 3.16 ms per loop 

#pir's solution 1 
In [66]: %timeit list({k: 1 for x in df.available_fruits.values.tolist() for k in x}) 
100 loops, best of 3: 4.59 ms per loop 

#pir's solution 2 
In [67]: %%timeit 
    ...: from sklearn.preprocessing import MultiLabelBinarizer 
    ...: 
    ...: mlb = MultiLabelBinarizer() 
    ...: mlb.fit(df.available_fruits) 
    ...: list(mlb.classes_) 
    ...: 
100 loops, best of 3: 4.07 ms per loop 

#perigon's solution 
In [68]: %timeit list(set([val for lst in df.available_fruits for val in lst])) 
100 loops, best of 3: 5.1 ms per loop 
+3

我不敢回答,當我看到'問題dataframe'標籤,因爲我知道沒有人能夠擊敗jezrael說到熊貓,我很佩服你的哥們,從你們學到了很多東西,謝謝:) + 1 –

+0

@akashkarothiya繼續嘗試好友。你有一天會到達那裏。哦,+1 btw。 –

+0

謝謝@cᴏʟᴅsᴘᴇᴇᴅ:)對我來說這意味着很多 –

2

如果你有一組作爲輸出OK:

set([val for lst in df.available_fruits for val in lst]) 

當然,你可以將它轉換到一個列表:

list(set([val for lst in df.available_fruits for val in lst])) 
+1

這是最快的方法之一。 – piRSquared

5

的另一種方法,使用列表連接和setsum上列表加入他們。

In [779]: list(set(df.available_fruits.sum())) 
Out[779]: ['tomato', 'kiwi', 'apple', 'banana'] 

但是,使用來自@jezrael chain.from_iterable方法或@周角的扁平列表的方式。

5

選項0

from cytoolz import concat 

list(set(concat(df.available_fruits.values.tolist()))) 

選項1

list({k: 1 for x in df.available_fruits.values.tolist() for k in x}) 

['apple', 'banana', 'tomato', 'kiwi'] 

選項2
左場...

from sklearn.preprocessing import MultiLabelBinarizer 

MultiLabelBinarizer().fit(df.available_fruits).classes_.tolist() 

['apple', 'banana', 'kiwi', 'tomato'] 

時序
結論:

  • 最快過小數據:
    • pir1jez2
  • 最快的大型資料
    • pir2,非常接近jez2

results.div(results.min(1), 0).round(2).pipe(lambda d: d.assign(Best=d.idxmin(1))) 

     pir0 pir1 pir2  galt jez1 jez2 prgn Best 
N               
1  2.36 1.00 4.43 13.93 10.82 1.00 2.86 pir1 
3  1.67 1.51 3.94 12.27 7.20 1.00 2.73 jez2 
10  1.59 1.09 4.90  9.90 9.24 1.00 3.03 jez2 
30  1.20 1.39 2.44  6.78 9.42 1.00 2.67 jez2 
100 1.06 1.45 1.66 12.15 20.50 1.00 2.00 jez2 
300 1.13 1.76 1.33 28.30 33.41 1.00 2.01 jez2 
1000 1.00 1.70 1.11 111.74 32.79 1.18 1.95 pir0 
3000 1.00 1.93 1.02 364.07 32.18 1.03 2.02 pir0 
10000 1.08 1.87 1.00 1223.63 35.10 1.03 1.97 pir2 

enter image description here

代碼

pir0 = lambda df: list(set(concat(df.available_fruits.values.tolist()))) 
pir1 = lambda df: list({k: 1 for x in df.available_fruits.values.tolist() for k in x}) 
pir2 = lambda df: MultiLabelBinarizer().fit(df.available_fruits).classes_.tolist() 
galt = lambda df: list(set(df.available_fruits.sum())) 
jez1 = lambda df: np.unique(np.concatenate(df['available_fruits'].values.tolist())).tolist() 
jez2 = lambda df: list(set(chain.from_iterable(df.available_fruits.values.tolist()))) 
prgn = lambda df: list(set([val for lst in df.available_fruits for val in lst])) 

results = pd.DataFrame(
    index=pd.Index([1, 3, 10, 30, 100, 300, 1000, 3000, 10000, 30000], name='N'), 
    columns='pir0 pir1 pir2 galt jez1 jez2 prgn'.split(), 
    dtype=float 
) 

for i in results.index: 
    d = pd.concat([df] * i, ignore_index=True) 
    for j in results.columns: 
     stmt = '{}(d)'.format(j) 
     setp = 'from __main__ import d, {}'.format(j) 
     results.set_value(i, j, timeit(stmt, setp, number=10)) 

fig, (a1, a2) = plt.subplots(1, 2, figsize=(10, 10)) 
results.plot(loglog=True, ax=a1) 
results.div(results.min(1), 0).round(2).plot.barh(logx=True, ax=a2) 
+1

爲簡潔起見,它可以是'list({k for x in dff.available_fruits for k in x})'? – Zero

+0

@JohnGalt謝謝 – piRSquared

相關問題