我在pandas中有一个dataframeA和dataframeB,我想更新A的一个列,如果某行的某些条件在B中匹配,我想在多个条件匹配时,对当前行应用一个名为“similar”的函数,如下所示:
def similar(a, b):
match_ratio = SequenceMatcher(None, a, b).ratio()
if match_ratio > 0.6:
return True
else:
return False
def updateLabel(repo_name, str_a):
str_to_check = re.sub('[^a-zA-Z0-9]+', '', str_a)
data = B.loc[(B['repo_name'] == repo_name) & similar(B["sanitized_str_b"], str_to_check)]
if len(data) > 0:
return "TP"
return "FP"
A["label"] = A[["repo_name", "str_a"]].apply(lambda x: updateLabel(x.repo_name, x.str_a), axis = 1)
但是,它抛出了一个错误。然后我试着像下面这样,但它非常慢。
def updateLabel(repo_name, str_a):
str_to_check = re.sub('[^a-zA-Z0-9]+', '', str_a)
def similar(a):
match_ratio = SequenceMatcher(None, a, str_to_check).ratio()
if match_ratio > 0.6:
return True
else:
return False
data = B.loc[(B['repo_name'] == repo_name)]
data = B.loc[data.sanitized_str_b.apply(similar)]
if len(data) > 0:
return "TP"
return "FP"
A["label"] = A[["repo_name", "str_a"]].apply(lambda x: updateLabel(x.repo_name, x.str_a), axis = 1)
通过调用panda中的函数来过滤一个有多个条件和条件的 Dataframe ,正确的方法是什么?
2条答案
按热度按时间af7jpaap1#
如果包含一个minimal reproducible example,提供优化线索会更容易。不过,我看到了一种提高速度的方法:如果只是检查
data
的长度是否大于0,则不需要使用apply(similar)
过滤data
。使用any
:4nkexdtk2#
看起来您想要“模糊匹配”
str
列。与
SequenceMatcher
相比,有更快的选项,例如RapidFuzz-在stackoverflow上有各种pandas/rapidfuzz示例。由于您还希望在
repo_name
上进行相等匹配,因此可以使用原生支持这两种操作的东西,例如duckdbduckdb可以read from pandas dataframes:
然后可以根据
NULL
值分配TP/FP
结果。jaro_winkler_similarity()
被用作记分器。.df()
可用于将结果转换为pandas Dataframe