提问人:Sevval 提问时间:11/14/2023 最后编辑:Sevval 更新时间:11/15/2023 访问量:96
如何加速熊猫应用函数与for循环?(蟒蛇)
How to speed up pandas apply function with for loops? (Python)
问:
我正在为我的项目编写文本。
我想通过在字典中查找所有单词来替换数据集文本中的单词。
我的字典是这样的;replacement_dict ={'t1' : 'tebir', 't2':'teki', 'number':'no', ...}
数据帧中的示例文本;将是 ;"Hello my t1 is not okey, please help my number is bla bla"
"Hello my tebir is not okey, please help my no is bla bla"
我写了以下代码;
import pandas
def replacament(row,replacement_dict):
text = row['text']
text = text.lower()
for i, j in replacement_dict.items():
text = re.sub(r"\b%s\b" % i, j, text)
return text
data['text2'] = data.apply(replacament, axis = 1, args=(replacement_dict,))
但需要 8 小时才能完成。我的日期集行大小是 600000。我怎样才能加快这个应用功能? 谢谢
答:
1赞
user19077881
11/14/2023
#1
apply
可能相当慢,但 pandas 有一个功能,可以通过首先使用正则表达式形成另一个字典来使用,以仅替换整个单词(假设您只想替换单词而不是单词中的子字符串),如下所示。600,000 行大约需要 10-15 秒。replace
d = {r'(\b){}(\b)'.format(k):r'\1{}\2'.format(v) for k,v in replacement_dict.items()}
df['text2'] = df['text'].str.lower().replace(d, regex = True)
评论
0赞
MatBailie
11/14/2023
您错过了 OP 的部分。 需要不区分大小写。lower()
0赞
user19077881
11/15/2023
@MatBailie 谢谢。答案已编辑。我的想法是基于OP文本中没有上限。
0赞
Ömer Sezer
11/14/2023
#2
也许 (https://github.com/jmcarpenter2/swifter) + 对你有帮助 ()。swifter
pandas.DataFrame.replace
pip install swifter
我更新了您的输入并为测试创建了 600K 行。这需要 1.43 秒。
法典:
import re
import swifter
import pandas as pd
import time
data = pd.DataFrame({'text': ["t2 my t1 is not okey, number please help my is bla bla"] * 600000})
replacement_dict = {'t1': 'tebir', 't2': 'teki', 'number': 'no'}
start_time = time.time()
def replace_text(text):
for k, v in replacement_dict.items():
text = text.replace(k, v)
return text
data['text2_parallel'] = data['text'].swifter.apply(replace_text)
parallel_time = time.time() - start_time
print(f"Parallelized time: {parallel_time:.2f} seconds")
print(data[['text2_parallel']])
输出:
Pandas Apply: 100%|████████████████████████████████████████████████████████| 600000/600000 [00:01<00:00, 458107.50it/s]
Parallelized time: 1.43 seconds
text2_parallel
0 teki my tebir is not okey, no please help my ...
1 teki my tebir is not okey, no please help my ...
2 teki my tebir is not okey, no please help my ...
3 teki my tebir is not okey, no please help my ...
4 teki my tebir is not okey, no please help my ...
... ...
599995 teki my tebir is not okey, no please help my ...
599996 teki my tebir is not okey, no please help my ...
599997 teki my tebir is not okey, no please help my ...
599998 teki my tebir is not okey, no please help my ...
599999 teki my tebir is not okey, no please help my ...
[600000 rows x 1 columns]
1赞
Melcore
11/14/2023
#3
使用熊猫。DataFrame.replace
函数。
像这样使用它,正则表达式参数为 True
import pandas
test = pandas.DataFrame({"name": ["Good morning England", "Land and Freedom", "This is England"]})
replace_dict = {"England" : "French", "morning": "night"}
test["name"] = test["name"].replace(replace_dict, regex=True)
print(test)
测试数据帧现在是:
name
0 Good night French
1 Land and Freedom
2 This is French
评论
0赞
Sevval
11/14/2023
感谢您的回答,我在哪里可以在此替换函数中添加较低的函数
1赞
Bushmaster
11/14/2023
@Melcore,如果 dataFrame 中调用了一个值,则输出将为 。所以你的解决方案不太正确。您必须使用正则表达式规则 (\b%s\b)wwEnglandww
wwFrenchww
0赞
Sevval
11/14/2023
字典元素已经应用在较低的位置,因此我只需要降低 DataFrame 文本
0赞
Sevval
11/14/2023
但是这个文本是土耳其语,所以我使用的是 unicode_tr(text).lower()
下一个:如何根据R中的条件替换多列中的值
评论
replacement
data['text2'] = data['text'].str.lower()
for k, v in replacement_dict.items(): data['text2'] = data['text'].str.replace(r'\b%s\b' % k, v)