gpt4 book ai didi

python - 使用字符串匹配慢来切片 Pandas 行

转载 作者:太空狗 更新时间:2023-10-29 21:51:58 33 4
gpt4 key购买 nike

我基本上想学习一种基于正则表达式的条件切片来更快地切片 Pandas 数据帧的方法。例如下面的 df(string_column 有 4 个以上的变体,它们仅用于说明目的):

index, string_col1, string_col2, value
0, 'apple', 'this', 10
1, 'pen', 'is', 123
2, 'pineapple', 'sparta', 20
3, 'pen pineapple apple pen', 'this', 234
4, 'apple', 'is', 212
5, 'pen', 'sparta', 50
6, 'pineapple', 'this', 69
7, 'pen pineapple apple pen', 'is', 79
8, 'apple pen', 'sparta again', 78
...
100000, 'pen pineapple apple pen', 'this is sparta', 392

我必须使用正则表达式根据 string_column 进行 bool 条件切片,同时在 value 列中找到具有最小值和最大值的索引,然后最后找到最小值和最大值之间的差异。我通过以下方法执行此操作,但是当我必须匹配许多不同的正则表达式模式时它非常慢:

pat1 = re.compile('apple')
pat2 = re.compile('sparta')
mask = (df['string_col1'].str.contains(pat1)) & (df['string_col2'].str.contains(pat2))
max_idx = df[mask].idxmax()
min_idx = df[mask].idxmin()
difference = df['value'].loc[max_idx] - df['value'].loc[min_idx]

我想得到一个“不同”的答案,我对 df 进行了太多次切片,但我想不出如何减少它。此外,有没有更快的切片方法?

这是一个优化问题,因为我知道我的代码可以满足我的需求。任何提示将不胜感激!

最佳答案

我一直在尝试分析您的示例,但实际上我在合成数据上获得了相当不错的性能,因此我可能需要一些说明。 (此外,出于某种原因,每当我的数据框中有字符串时,.idxmax() 就会中断)。

这是我的测试代码:

import pandas as pd
import re
import numpy as np
import random
import IPython
from timeit import default_timer as timer

possibilities_col1 = ['apple', 'pen', 'pineapple', 'joseph', 'cauliflower']
possibilities_col2 = ['sparta', 'this', 'is', 'again']
entries = 100000
potential_words_col1 = 4
potential_words_col2 = 3
def create_function_col1():
result = []
for x in range(random.randint(1, potential_words_col1)):
result.append(random.choice(possibilities_col1))
return " ".join(result)

def create_function_col2():
result = []
for x in range(random.randint(1, potential_words_col2)):
result.append(random.choice(possibilities_col2))
return " ".join(result)

data = {'string_col1': pd.Series([create_function_col1() for _ in range(entries)]),
'string_col2': pd.Series([create_function_col2() for _ in range(entries)]),
'value': pd.Series([random.randint(1, 500) for _ in range(entries)])}


df = pd.DataFrame(data)
pat1 = re.compile('apple')
pat2 = re.compile('sparta')
pat3 = re.compile('pineapple')
pat4 = re.compile('this')
#IPython.embed()
start = timer()
mask = df['string_col1'].str.contains(pat1) & \
df['string_col1'].str.contains(pat3) & \
df['string_col2'].str.contains(pat2) & \
df['string_col2'].str.contains(pat4)
valid = df[mask]
max_idx = valid['value'].argmax()
min_idx = valid['value'].argmin()
#max_idx = result['max']
#min_idx = result['min']
difference = df.loc[max_idx, 'value'] - df.loc[min_idx, 'value']
end = timer()
print("Difference: {}".format(difference))
print("# Valid: {}".format(len(valid)))
print("Time Elapsed: {}".format(end-start))

您能解释一下您申请了多少条件吗? (我添加的每个正则表达式只会增加大致线性的时间增加(即 2->3 正则表达式意味着运行时间增加 1.5 倍))。我还对条目数量和两个潜在字符串长度(potential_words 变量)进行了线性缩放。

作为引用,这段代码在我的机器上的计算时间约为 0.15 秒(100 万个条目需要 1.5 秒)。

编辑:我是个白痴,并没有做同样的事情(我正在计算数据集中最小和最大索引值之间的差异,而不是最小值和最大值之间的差异),但是修复它并没有真正增加运行时间。

编辑 2:idxmax() 如何知道在您的示例代码中选择哪一列的最大值?

关于python - 使用字符串匹配慢来切片 Pandas 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45221192/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com