Python 列表篩選數據詳解

在做數據處理中,常會遇到列表篩選,比如有以下兩個列表:

根據上列表中的KEY1 , 篩選下列表的數據,也就是標黃的數據。數量不大的情況,一般就是遍歷比較,邏輯簡單,幾行代碼搞掂。

但如果列表達到萬,或者百萬、千萬,那遍歷效率就低瞭。

先構造測試的列表。

# 構造篩選目標列表,確保KEY不重復
n1 = 30000
n1_set = set([random.randint(1,n1)  for n in range(n1)])
n1 = len(n1_set)
list1 = [['1108{:0>6d}27'.format(n), "".join(random.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',10))] for n in n1_set]
# 構造待篩選數據列表,確保KEY不重復
n2 = 100000
n2_set = set([random.randint(1,n2)  for n in range(n2)])
n2= len(n2_set)
list2 = [['1108{:0>6d}27'.format(n), "".join(random.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',5)),n ] for n in n2_set]

比較遍歷、列表生成式+filter 、pandas 的 merge 三種方法效率。

篩選目標18971條, 待處理數據63275條
遍歷生成數據 耗時11.591秒 獲得數據量 12024
['11080000427', 'eArVD', 4]
filter 耗時11.5秒 獲得數據量 12024
['11080000427', 'eArVD', 4]
merge 耗時0.058秒 獲得數據量 12024
['11080000427', 'eArVD', 4]
篩選目標189733條, 待處理數據632363條
遍歷生成數據 耗時1597.4296秒 獲得數據量 120180
['1108000000227', 'NkoEQ', 2]
filter 耗時1575.0432秒 獲得數據量 120180
['1108000000227', 'NkoEQ', 2]
merge 耗時0.64秒 獲得數據量 120180
['1108000000227', 'NkoEQ', 2]

經過比較, 直接遍歷生成和列表生成式+filter的效率基本一致, pandas 的merge 效率最高。適合大批量數據處理。

上代碼

print("篩選目標{}條, 待處理數據{}條".format(n1,n2))
# 直接遍歷生成數據,計時
t1 = time.time()
list_temp = [n[0] for n in list1]
list3 = []
for n in list2:
    if n[0] in list_temp:
        list3.append(n)
t2 = time.time()
print("遍歷生成數據 耗時{}秒".format(round(t2 - t1, 4)), "獲得數據量", len(list3))
print(list3[0])
# 用filter篩選數據,計時
t1 = time.time()
list_temp = [n[0] for n in list1]
list3 = [n for n in filter(lambda x: x[0] in list_temp, list2)]
t2 = time.time()
print("filter 耗時{}秒".format(round(t2 - t1,4)), "獲得數據量", len(list3))
print(list3[0])
# 用pd.merge 篩選數據,計時
t1 = time.time()
df1 = pd.DataFrame(list1, columns=['k1','m1'])
df2 = pd.DataFrame(list2, columns=['k1','m2','n2'])
df3 = pd.merge(df1[['k1']], df2, how='inner', on='k1')
t2 = time.time()
print("merge 耗時{}秒".format(round(t2 - t1,4)), "獲得數據量", len(df3))
print(list(df3.iloc[0]))

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: