Re: [問題]不用for迴圈尋找陣列中只出現過一次的資料
※ 引述《sariel0322 (sariel)》之銘言:
: 我想要請問一下,如果我有一串數字
: A = [9,5,5,4,7,6,4,1,2,0,10,9,7,....]
: 要如何找出這列資料中只出現一次的數字,但不用到for迴圈的方法
(冏冏,我看成有出現就好…… 明天再補了 > <)
完整檔案見 IPython Notebook
http://nbviewer.ipython.org/gist/ccwang002/bc1b047d0eca2c8f8bdd
這真的要快的話,就不應該自己寫 for loop,所以我想得到最快的方法就是用 set(A)
但有沒有更快的方式呢?其中一個可能是用 Cython, cffi 自己刻一個,
但 numpy.unique() 不知道快不快? 直覺上以為是會快很多的,所以來個實測。
# Test by IPython on Python 3.4
import numpy as np
LEN = 10**7 # 約需要總共 200MB 的記憶體
# 整數
A = np.random.randint(0, 100, LEN) # numpy 陣列 (ndarray)
A_list = A.tolist() # 一般的 list
%timeit -n 5 np.unique(A) # numpy 解法
%timeit -n 5 set(A_list) # set() 解法
%timeit set(A) # 混用,對 numpy 陣列用 set()
# 448ms, 232ms, 1.67s
# 5.18s, 2.31s, - s if LEN = 10**8
結果 set() 跑得比 np.unique() 還快,蠻驚訝的 > < 資料量調大仍舊相同的趨勢。
混用很可怕,這小測試暗示 ndarray 用內建函式的時候,很可能會做非常多轉換,
很容易拖慢速度。而內建的指令其實速度飛快。
但這樣 numpy 哪裡有優勢,是否該洗洗睡?我猜它在浮點數表現就會好很多,
浮點數找相同的數值有點怪,但總之要幫 numpy 平反也不管這麼多了xd
# 浮點數版本,只會有 0.0, 0.1, 0.2, ...
A = np.random.randint(0, 100, LEN) / 10
A_list = A.tolist()
%timeit -n 5 np.unique(A)
%timeit -n 5 set(A_list)
%timeit -n 5 set(A)
# 698ms, 1.55s, 2.23s
果然 numpy 的效率就好很多。
恩…總之蠻好玩的。
PS Py 3.4 中多了 tracemalloc module 可以追蹤程式執行間記憶體用量
https://docs.python.org/3/library/tracemalloc.html
看 Python 物件記憶體用量(?) 可用 sys.getsizeof(obj)
看 Numpy .............. 可用 ndarray_obj.nbytes
--
PyCon APAC 2014/TW is coming! May 17-18 @中研院人社館
More info on https://tw.pycon.org/2014apac/zh/
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.217.22
※ 文章網址: http://www.ptt.cc/bbs/Python/M.1399836156.A.6F6.html
推
05/12 11:09, , 1F
05/12 11:09, 1F
推
05/12 11:22, , 2F
05/12 11:22, 2F
→
05/12 11:23, , 3F
05/12 11:23, 3F
→
05/12 11:24, , 4F
05/12 11:24, 4F
→
05/12 11:24, , 5F
05/12 11:24, 5F
喔喔,我的猜測是 tracemalloc 它是在 python 分配記憶體的時候多加一個 hook
來記錄每行程式記憶體的增減,但 numpy 在 malloc 的時候不是用 python 的版本
所以 tracemalloc 裡會看不到 A (numpy obj) 的大小。
如果要看的話就要使用 numpy API 的 A.nbytes。
不過這個問題可能在 Py 3.5 + numpy 1.9(2.0?) 就會被解決了,python mail list
已經在討論相關的可行性 http://bugs.python.org/issue21233
http://mail.scipy.org/pipermail/numpy-discussion/2014-April/069935.html
但我蠻意外的是兩者的大小竟然差不多
我以為 numpy 的實作記憶體用量會小 list 的不少,是不是我搞錯什麼了 @@
→
05/12 21:30, , 6F
05/12 21:30, 6F
→
05/12 21:30, , 7F
05/12 21:30, 7F
→
05/12 21:31, , 8F
05/12 21:31, 8F
感謝分享!
※ 編輯: ccwang002 (140.112.129.20), 05/14/2014 11:34:06
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 5 篇):