我們有一個給定的串列:
list_of_versions = ['apple II' ,'apple', 'apple 1' , 'HD APPLE','apple 3.5', 'adventures of apple' , 'apple III','orange 2' ,'300mhz apple', '300-orange II' , 'orange II HD' , 'orange II tvx', 'orange 2' , 'HD berry-vol 2', 'berry II', 'berry 2', 'berry VI', 'berry 1', 'berry II' ,'berry' ,'II Berry']
如何找到每個字串的主要單詞?例如:
word | main
--------------------------
apple II |apple
val/apple |apple
apple 1 |apple
HD APPLE |apple
apple 3.5 |apple
adventures of apple |apple
apple III |apple
300mhz apple |apple
orange 2 |orange
300-orange II |orange
orange II HD |orange
/orange/II-tvx |orange
orange 2 |orange
HD berry-vol 2 |berry
berry-II |berry
-berry-2 |berry
(berry) VI |berry
berry 1 |berry
berry II |berry
berry 2022 B8 |berry
II Berry-hd |berry
22 Berry II |berry
Berry 6.8.9 |berry
要點:
我無法創建包含三個主要單詞(apple、orange、berry)的主要單詞串列。因為串列將使用新的主要單詞進行更新。所以我們永遠不會知道什么是新詞。
版本沒有限制。在某些時候,我們可以看到像“apple XII”或“GB-HD berry 2.4”這樣的東西,所以版本價值可以決定一切。(如果你想創建一個停用詞串列)
很高興(但不是強制性的)--> 添加另一個顯示版本的列。IE:
word | main | version
-----------------------------------
apple II |apple | II
val/apple |apple | NULL
apple 1 |apple | 1
HD APPLE |apple | HD
apple 3.5 |apple | 3.5
apple III |apple | III
300mhz apple II |apple | II
orange 2 |orange | 2
300-orange II |orange | II
orange II HD |orange | II HD
/orange/II-tvx |orange | II tvx
orange 2 |orange | 2
HD berry-vol 2 |berry | 2 HD
berry-II |berry | II
-berry-2 |berry | 2
(berry) VI |berry | VI
berry 1 |berry | 1
berry II |berry | II
berry 2022 |berry | NULL
II Berry-hd |berry | II HD
22 Berry |berry | 22
Berry 6.8.9 |berry | 6.8.9
uj5u.com熱心網友回復:
所有其他答案都省略了包含“冒險”一詞的條目,因為它會引發搜索。您需要一個可以將“最長”與“最頻繁”結合起來的啟發式方法。
有幫助的一件事是,在每一行中找到最長的單詞會大大提高 SNR。換句話說,它很好地過濾掉了不必要的單詞,只需要一點幫助。如果您知道要查找多少個單詞(在本例中為三個),則一切就緒:
from collections import Counter
common_long_words = [word.casefold() for word in (max(re.findall('\\w ', version), key=len) for version in list_of_versions)]
words = Counter(common_long_words).most_common(3)
拆分版本并找到感興趣的單詞并不是特別困難。關于版本的構成,您有幾個選擇,尤其是當主詞嵌入短語中間時。這是一個簡單的函式,它取整個余數:
def split_main(version, words):
for word in words:
i = version.find(word)
if i > 0:
return word, f'{version[:i]} {version[i len(word)]}'
else:
raise ValueError(f'Version "{version}" does not contain any of the main words {{{", ".join(words)}}}')
result = {version: split_main(version, words) for version in list_of_versions}
uj5u.com熱心網友回復:
我建議您的任務遵循啟發式:找到最長的字母序列,可以使用re以下方式使用模塊來實作
import re
list_of_versions = ['apple II' ,'apple', 'apple 1' , 'HD APPLE','apple 3.5', 'apple III','orange 2' ,'300mhz apple', '300-orange II' , 'orange II HD' , 'orange II tvx', 'orange 2' , 'HD berry-vol 2', 'berry II', 'berry 2', 'berry VI', 'berry 1', 'berry II' ,'berry' ,'II Berry']
def get_main(string):
return max(re.findall(r'[A-Za-z] ',string),key=len)
for version in list_of_versions:
print(version,'|',get_main(version))
輸出
apple II | apple
apple | apple
apple 1 | apple
HD APPLE | APPLE
apple 3.5 | apple
apple III | apple
orange 2 | orange
300mhz apple | apple
300-orange II | orange
orange II HD | orange
orange II tvx | orange
orange 2 | orange
HD berry-vol 2 | berry
berry II | berry
berry 2 | berry
berry VI | berry
berry 1 | berry
berry II | berry
berry | berry
II Berry | Berry
警告:此解決方案僅限于 ASCII 字母,并且僅使用您的示例資料準備,請使用您可以訪問的所有資料對其進行測驗,以檢測是否確實為您的用例回傳了您想要的足夠頻繁的內容。
uj5u.com熱心網友回復:
正如評論中所建議的,您可以獲得最長的字串:
df['main'] = (df['words']
.str.extractall('([a-zA-Z] )')
.sort_values(by=0, key=lambda x: x.str.len())
.groupby(level=0).last()
[0].str.lower() # optional
)
輸出:
words main
0 apple II apple
1 apple apple
2 apple 1 apple
3 HD APPLE apple
4 apple 3.5 apple
5 apple III apple
6 orange 2 orange
7 300mhz apple apple
8 300-orange II orange
9 orange II HD orange
10 orange II tvx orange
11 orange 2 orange
12 HD berry-vol 2 berry
13 berry II berry
14 berry 2 berry
15 berry VI berry
16 berry 1 berry
17 berry II berry
18 berry berry
19 II Berry berry
嘗試“版本”:保留所有其他單詞
選項1
g = (df['words']
.str.extractall(r'\b([a-zA-Z] )\b')
.sort_values(by=0, key=lambda x: x.str.len())
.droplevel(1)
.groupby(level=0, group_keys=False)[0]
)
df['main'] = g.last().str.lower()
df['version'] = g.apply(lambda x: ' '.join(x.iloc[:-1]))
輸出:
words main version
0 apple II apple II
1 apple apple
2 apple 1 apple
3 HD APPLE apple HD
4 apple 3.5 apple
5 apple III apple III
6 orange 2 orange
7 300mhz apple apple
8 300-orange II orange II
9 orange II HD orange HD II
10 orange II tvx orange II tvx
11 orange 2 orange
12 HD berry-vol 2 berry HD vol
13 berry II berry II
14 berry 2 berry
15 berry VI berry VI
16 berry 1 berry
17 berry II berry II
18 berry berry
19 II Berry berry II
option2(不同的正則運算式和長度計算)
g = (df['words']
.str.extractall(r'(\b\w \b)')
.sort_values(by=0, key=lambda x: x.str.replace('[^a-zA-Z]', '', regex=True)
.str.len())
.droplevel(1)
.groupby(level=0, group_keys=False)[0]
)
df['main'] = g.last().str.lower()
df['version'] = g.apply(lambda x: ' '.join(x.iloc[:-1]))
輸出:
words main version
0 apple II apple II
1 apple apple
2 apple 1 apple 1
3 HD APPLE apple HD
4 apple 3.5 apple 3 5
5 apple III apple III
6 orange 2 orange 2
7 300mhz apple apple 300mhz
8 300-orange II orange 300 II
9 orange II HD orange HD II
10 orange II tvx orange II tvx
11 orange 2 orange 2
12 HD berry-vol 2 berry 2 HD vol
13 berry II berry II
14 berry 2 berry 2
15 berry VI berry VI
16 berry 1 berry 1
17 berry II berry II
18 berry berry
19 II Berry berry II
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/451012.html
