How to compile all lists in a column into one unique list

后端 未结 4 1260
有刺的猬
有刺的猬 2020-12-10 15:28

I have a pandas dataframe as below:

How can I combine all the lists (in the \'val\' column) into a unique list (set), e.g. [val1, val2, val33, val9, v

相关标签:
4条回答
  • 2020-12-10 15:45

    Another solution with exporting Series to nested lists and then apply set to flatten list:

    df = pd.DataFrame({'id':['a','b', 'c'], 'val':[['val1','val2'],
                                                   ['val33','val9','val6'],
                                                   ['val2','val6','val7']]})
    
    print (df)
      id                  val
    0  a         [val1, val2]
    1  b  [val33, val9, val6]
    2  c   [val2, val6, val7]
    
    print (type(df.val.ix[0]))
    <class 'list'>
    
    print (df.val.tolist())
    [['val1', 'val2'], ['val33', 'val9', 'val6'], ['val2', 'val6', 'val7']]
    
    print (list(set([a for b in df.val.tolist() for a in b])))
    ['val7', 'val1', 'val6', 'val33', 'val2', 'val9']
    

    Timings:

    df = pd.concat([df]*1000).reset_index(drop=True)
    
    In [307]: %timeit (df['val'].apply(pd.Series).stack().unique()).tolist()
    1 loop, best of 3: 410 ms per loop
    
    In [355]: %timeit (pd.Series(sum(df.val.tolist(),[])).unique().tolist())
    10 loops, best of 3: 31.9 ms per loop
    
    In [308]: %timeit np.unique(np.hstack(df.val)).tolist()
    100 loops, best of 3: 10.7 ms per loop
    
    In [309]: %timeit (list(set([a for b in df.val.tolist() for a in b])))
    1000 loops, best of 3: 558 µs per loop
    

    If types is not list but string use str.strip and str.split:

    df = pd.DataFrame({'id':['a','b', 'c'], 'val':["[val1,val2]",
                                                   "[val33,val9,val6]",
                                                   "[val2,val6,val7]"]})
    
    print (df)
      id                val
    0  a        [val1,val2]
    1  b  [val33,val9,val6]
    2  c   [val2,val6,val7]
    
    print (type(df.val.ix[0]))
    <class 'str'>
    
    print (df.val.str.strip('[]').str.split(','))
    0           [val1, val2]
    1    [val33, val9, val6]
    2     [val2, val6, val7]
    Name: val, dtype: object
    
    print (list(set([a for b in df.val.str.strip('[]').str.split(',') for a in b])))
    ['val7', 'val1', 'val6', 'val33', 'val2', 'val9']
    
    0 讨论(0)
  • 2020-12-10 15:54

    One way would be to extract those elements into an array using np.hstack and then using np.unique to give us an array of such unique elements, like so -

    np.unique(np.hstack(df.val))
    

    If you want a list as output, append with .tolist() -

    np.unique(np.hstack(df.val)).tolist()
    
    0 讨论(0)
  • 2020-12-10 15:56

    Convert that column into a DataFrame with .apply(pd.Series). If you stack the columns, you can call the unique method on the returned Series.

    df
    Out[123]: 
                val
    0      [v1, v2]
    1      [v3, v2]
    2  [v4, v3, v2]
    

    df['val'].apply(pd.Series).stack().unique()
    Out[124]: array(['v1', 'v2', 'v3', 'v4'], dtype=object)
    
    0 讨论(0)
  • 2020-12-10 15:56

    You can use str.concat followed by some string manipulations to obtain the desired list.

    In [60]: import re
        ...: from collections import OrderedDict
    
    In [62]: s = df['val'].str.cat()
    
    In [63]: L = re.sub('[[]|[]]',' ', s).strip().replace("  ",',').split(',')
    
    In [64]: list(OrderedDict.fromkeys(L))
    Out[64]: ['val1', 'val2', 'val33', 'val9', 'val6', 'val7']
    
    0 讨论(0)
提交回复
热议问题