如何加速熊猫应用函数与for循环?(蟒蛇)

How to speed up pandas apply function with for loops? (Python)

提问人:Sevval 提问时间:11/14/2023 最后编辑:Sevval 更新时间:11/15/2023 访问量:96

问:

我正在为我的项目编写文本。 我想通过在字典中查找所有单词来替换数据集文本中的单词。 我的字典是这样的;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。我怎样才能加快这个应用功能? 谢谢

python 替换 apply

评论

0赞 Matt Pitkin 11/14/2023
你可以使用 stackoverflow.com/a/15175239/1862861 的答案,至少从你的函数中删除 for 循环,这有望提供一些加速。replacement
1赞 MatBailie 11/14/2023
Pandas 有自己的正则表达式替换,包括一个不区分大小写的标志......pandas.pydata.org/docs/reference/api/...... (完全避免应用、降低等。
0赞 Bushmaster 11/14/2023
你可以使用这样的东西:首先然后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)

答:

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) + 对你有帮助 ()。swifterpandas.DataFrame.replacepip 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)wwEnglandwwwwFrenchww
0赞 Sevval 11/14/2023
字典元素已经应用在较低的位置,因此我只需要降低 DataFrame 文本
0赞 Sevval 11/14/2023
但是这个文本是土耳其语,所以我使用的是 unicode_tr(text).lower()