剛剛測試弄了約一個77萬筆句子的[樣本]csv,把它命名為'big_data.csv',內容節錄如下:
it邦幫忙
人之所以痛苦 在於追求錯誤的東西
如果你不給自己煩惱 別人也永遠不可能給你煩惱
今日的執著
會造成明日的後悔
當你對自己誠實的時候
世界上沒有人能夠欺騙得了你
面對現實才能超越現實
不懂得自愛的人 是沒有能力去愛別人的
太陽底下沒有新鮮事
(註:77萬筆句子就是上面的這十行重覆7萬7千次)
然後是[詞庫]csv,把它命名為'small_data.csv',內容如下:
it
痛cool
追求錯誤
天天上班
很酷
新鮮事
最後是測試的python碼,我把它命名為'numpy_load_data_test.py',內容如下:
import numpy as np
import datetime
print('準備載入CSV: '+str(datetime.datetime.now())[:-7])
big_data = np.loadtxt('big_data.csv', delimiter=',', unpack=True, dtype=str,encoding="utf-8")
print('載入big_data.csv OK: '+str(datetime.datetime.now())[:-7])
small_data = np.loadtxt('small_data.csv', delimiter=',', unpack=True, dtype=str,encoding="utf-8")
print('載入small_data.csv OK: '+str(datetime.datetime.now())[:-7])
print('big_data筆數: '+str(len(big_data)))
print('比對開始: '+str(datetime.datetime.now())[:-7])
for A in small_data:
B=np.char.find(big_data, A)
B[B>-1]=1
B[B<0]=0
print(A,B)
print('比對結束: '+str(datetime.datetime.now())[:-7])
執行結果:
準備載入CSV: 2019-08-08 11:41:37
載入big_data.csv OK: 2019-08-08 11:41:43
載入small_data.csv OK: 2019-08-08 11:41:43
big_data筆數: 770902
比對開始: 2019-08-08 11:41:43
it [1 0 0 ... 0 0 0]
痛cool [0 0 0 ... 0 0 0]
追求錯誤 [0 1 0 ... 0 0 0]
天天上班 [0 0 0 ... 0 0 0]
很酷 [0 0 0 ... 0 0 0]
新鮮事 [0 0 0 ... 0 0 1]
比對結束: 2019-08-08 11:41:49
樓主有空可以試試看~
(載入big_data.csv花了約6秒)
跑詞庫迴圈比對big_data時每一圈花費1秒 6筆共花6秒,
如果是以樓主所說 詞庫有3000筆 那有可能總時會花費(3000/60)=50分鐘(粗估)
感謝你的回答,很實用
啊手機版不能用最佳解答,晚點給您
不客氣~~
回家來跑跑看純用list會多慢好了。XD
跑了一下,發現ccutmis你應該弄反了。
他要的是:
人之所以痛苦 在於追求錯誤的東西 [0 0 1 0 0 0]
.
.
.
不過轉置一下就好了。
def deal(readFileName,readFileName2):
read4replys = pd.read_excel(readFileName)
read4features=pd.read_excel(readFileName2)
replys=read4replys.iloc[ : , 0 ]
features=read4features.iloc[:,0]
replys=list(replys)
for A in features:
B=np.char.find(replys,A)
B[B>-1]=1
B[B<0]=0
很抱歉,我試了5000*3000的矩陣
結果我用暴力法比這個快3倍,請問我是哪裡做錯或者是有更好的建議嗎
不知道耶 你用暴力法比這個方法快3倍 那...
那就用暴力法好了~我的建議當作參考就好
太陽底下沒有新鮮事 但總有更好的路~
好吧,再次感謝
先分詞再以字元拼音做索引做成dict,搜尋速度會非常快
分詞你可以找 jieba 詞庫,目前收錄的中文詞庫語料真的很全,你可以參考看看
至於轉拼音或注音(做dict key用的),我個人是把分詞後的結果轉成拼音後存放,拼音字母只有26個字(沒扣掉絕對用不到的子音母音)
GitHub pypinyin
謝謝你分享的概念
全文檢索怕的不是關鍵字,而是錯別字漏字
比如清單裡有一組
『鄭中基 絕口不提!愛你』
如果使用者輸入搜尋"絕口不提愛你"
用比對法肯定找不到
所以我才建議用斷詞處理
『鄭中基 絕口不提!愛你』
用常用詞庫會裁成→"鄭中基 絕口不提 愛你"
(看你的語料詞庫的詳細程度決定)
我會把所有清單的內容,斷詞後做成
{"鄭中基": ["鄭中基 絕口不提!愛你","鄭中基 你的眼睛背叛了你的心","鄭中基 陳慧琳 北極雪"]}
{"絕口不提": ["鄭中基 絕口不提!愛你","【HD】柳岩-絕口不提","绝口不提 - 王曉晨"]}
{"愛你":["鄭中基 絕口不提!愛你","陳芳語-愛你","蔡依琳-愛你唷"])}
而你在接受使用者輸關鍵字詞,也做斷詞處理,只要對你分開的詞組DICT做搜尋,速度是 f(1),而你的方法得從頭到尾跑過一次,速度將會是f(n)
至於分詞結果轉成拼音或注音,就是怕用戶輸入錯別字
決口不堤?找不到
所以我是加了一層轉拼音的處置,這塊有點離題且是個人專利,留一手
我用在哪裡?自製的【語音智能音箱】裡,配上一支64GB USB隨身碟,機能不夠強,空間不夠大,塞NOSQL?我還是自己想辦法用上述的方法解決的
wow謝前輩指教,希望我有天能用上您的技巧
ㄜ...怎麼反而list比較快...Orz
list版本:
import datetime
start = datetime.datetime.now()
test_lst = [
"it邦幫忙",
"人之所以痛苦 在於追求錯誤的東西",
"如果你不給自己煩惱 別人也永遠不可能給你煩惱",
"今日的執著",
"會造成明日的後悔",
"當你對自己誠實的時候",
"世界上沒有人能夠欺騙得了你",
"面對現實才能超越現實",
"不懂得自愛的人 是沒有能力去愛別人的",
"太陽底下沒有新鮮事",
] * 77000
pat_lst = [
"it",
"痛cool",
"追求錯誤",
"天天上班",
"很酷",
"新鮮事"
]
def gen_exam_lst(pat, test_str):
return list(map(lambda x: 1 if x in test_str else 0, pat))
[print(t, gen_exam_lst(pat_lst, t)) for t in test_lst]
end = datetime.datetime.now()
print(end-start)
numpy版本:
import numpy as np
import datetime
start = datetime.datetime.now()
test_lst = [
"it邦幫忙",
"人之所以痛苦 在於追求錯誤的東西",
"如果你不給自己煩惱 別人也永遠不可能給你煩惱",
"今日的執著",
"會造成明日的後悔",
"當你對自己誠實的時候",
"世界上沒有人能夠欺騙得了你",
"面對現實才能超越現實",
"不懂得自愛的人 是沒有能力去愛別人的",
"太陽底下沒有新鮮事",
] * 77000
exam_lst = [
"it",
"痛cool",
"追求錯誤",
"天天上班",
"很酷",
"新鮮事"
]
big_data = np.asarray(test_lst)
small_data = np.asarray(exam_lst)
for A in big_data:
B=np.char.find(A, small_data)
B[B>-1]=1
B[B<0]=0
print(A,B)
end = datetime.datetime.now()
print(end-start)
在我機器上:
list版本:0:01:43.717999
numpy版本:0:02:42.642017
我寫的暴力法比您的簡單許多 速度也必較快 是因為 我的樣本數只有5000嗎?(我的比較方式是倍數) 還是因為有些函式的專長不是處理這個xdd
這個現象我也不知怎麼解釋內 之前沒實測比較過
但可以確定一點是 在不同電腦上算同樣的東西 時間也會不同
我的電腦跑你寫的numpy版本只需要一分多鐘
...樣本數5000和770000當然不能比啊。
你要比就要同樣資料不同方法去測試。