簡體   English   中英

Python:按唯一值分隔列表

[英]Python: separating a list by unique values

我有以下清單清單。

xlist =[['instructor','plb','error0992'],['instruction','address','00x0993'],['data','address','017x112']]]

我正在嘗試實現一個字符串算法,在該算法中,第一步需要將上述列表分成幾個列表。 分離標准是首先選擇最少數量的唯一令牌值,然后使用唯一令牌值將其分離。 (這是令牌是內部列表的元素)。 例如,在上面的xlist中,最少數量的唯一令牌位於第二索引=>(“ plb”,“地址”,“地址”)中。 因此,我需要將此列表分為以下兩個列表。

list1 = [['instruction','address','00x0993'],['data','address','017x112']]
list2=  [['instructor','plb','error0992']]

我是python的新手。 這是我的第一個項目。 有人可以建議我一個好方法嗎? 也許合適的列表理解? 或簡要說明我應該遵循的步驟。

純Python,在內存中,解決方案。 (當你有公羊的時候)

為了獲得名稱集,我轉置xlist,然后形成每個轉置元素的集合,這些元素將刪除所有重復項。

mintokenset只查找具有最少項目數的集合。

minindex查找內部列表mintokenset對應的列。

初始化名稱列表以具有足夠的空內部列表。

for循環使用該信息來適當地拆分內部列表。

>>> from pprint import pprint as pp
>>> 
>>> xlist =[['instructor','plb','error0992'],['instruction','address','00x0993'],['data','address','017x112']]
>>> sets = [set(transposedcolumn) for transposedcolumn in zip(*xlist)]
>>> pp(sets)
[{'instructor', 'data', 'instruction'},
 {'plb', 'address'},
 {'00x0993', '017x112', 'error0992'}]
>>> mintokenset = min(sets, key=lambda x:len(x))
>>> mintokenset
{'plb', 'address'}
>>> minindex = sets.index(mintokenset)
>>> minindex
1
>>> mintokens = sorted(mintokenset)
>>> mintokens
['address', 'plb']
>>> lists = [[] for _ in mintokenset]
>>> lists
[[], []]
>>> for innerlist in xlist:
    lists[mintokens.index(innerlist[minindex])].append(innerlist)


>>> pp(lists)
[[['instruction', 'address', '00x0993'], ['data', 'address', '017x112']],
 [['instructor', 'plb', 'error0992']]]
>>> 

在上面的Doodle之后,對於大數據 ,假設它存儲在文件中(每行一個內部列表,以逗號分隔)。 可以讀取該文件一次,並使用復雜的生成器表達式找到mintokenset和minindex,該表達式可以減少RAM需求。

類似地,使用另一個生成器表達式將輸出存儲在盡可能多的輸出文件中,以再次讀取輸入文件並將輸入記錄切換到其適當的輸出文件。

數據應流經很少的總體RAM使用量。

from pprint import pprint as pp

def splitlists(logname):
    with open(logname) as logf:
        #sets = [set(transposedcolumn) for transposedcolumn in zip(*(line.strip().split(',') for line in logf))]
        mintokenset, minindex = \
            min(((set(transposedcolumn), i)
                 for i, transposedcolumn in
                 enumerate(zip(*(line.strip().split(',') for line in logf)))),
                key=lambda x:len(x[0]))
    mintokens = sorted(mintokenset)
    lists = [open(r'C:\Users\Me\Code\splitlists%03i.dat' % i, 'w') for i in range(len(mintokenset))]
    with open(logname) as logf:
        for innerlist in (line.strip().split(',') for line in logf):
                lists[mintokens.index(innerlist[minindex])].write(','.join(innerlist) + '\n')
    for filehandle in lists:
        filehandle.close()

if __name__ == '__main__':
    # File splitlists.log has the following input
    '''\
instructor,plb,error0992
instruction,address,00x0993
data,address,017x112'''

    logname = 'splitlists.log'
    splitlists(logname)

    # Creates the following two output files:
    #   splitlists000.dat
    '''\
instruction,address,00x0993
data,address,017x112'''
    #   splitlists001.dat
    '''\
instructor,plb,error0992'''

既然您提到過這將是一個很大的數據集(有多大?),所以我認為pandas可能是這里最好的方法。

In [1]:
import numpy as np
import pandas as pd

In [4]:
xlist =[['instructor','plb','error0992'],['instruction','address','00x0993'],['data','address','017x112']]
df=pd.DataFrame(xlist, columns=['c1','c2','c3'])

In [6]:
set(df['c2'])

Out[6]:   
{'address', 'plb'}

In [11]:   
print df[df['c2']=='address']

            c1       c2       c3
1  instruction  address  00x0993
2         data  address  017x112

In [12]:   
print df[df['c2']=='plb']

           c1   c2         c3
0  instructor  plb  error0992

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM