Python Pandas-更换回路以提高效率

Python Pandas-更换回路以提高效率,python,pandas,performance,for-loop,dataframe,Python,Pandas,Performance,For Loop,Dataframe,我有一个数据帧(df) 和一个包含元素的列表 list ['ABC','HG','FL','200','CP1'] 现在我有以下代码: for idx, row in df.iterrows(): for item in list: if row['text'].strip().endswith(item): if pd.isnull(row['reference']): df.at[idx, 'resul

我有一个数据帧(df)

和一个包含元素的列表

list
['ABC','HG','FL','200','CP1']
现在我有以下代码:

for idx, row in df.iterrows(): 

    for item in list:

        if row['text'].strip().endswith(item):

            if pd.isnull(row['reference']):
                df.at[idx, 'result'] = item

            elif pd.notnull(row['reference']) and row['reference'] != item:                
                df.at[idx, 'result'] = 'wrong item'

            if pd.isnull(row['result']):
                break
我浏览了df和列表,并检查是否匹配

输出:

    No    text reference      result
0  123  60 ABC       ABC            
1  234    1nHG        HG            
2  345   KL HG        FL  wrong item
3  456   21ABC                   ABC
4  567   K 200       200            
5  678   1g HG                    HG
break指令很重要,因为否则在列表中会找到第二个元素,然后该第二个元素将覆盖结果中的内容

现在我需要另一个解决方案,因为数据帧很大,for循环效率很低。认为使用apply可以工作,但如何工作


谢谢大家!

您可以迭代后缀,而不是迭代行,这可能是一个小得多的iterable。这样,您就可以利用基于系列的方法和布尔索引

我还创建了一个额外的系列来标识行何时被更新。与按行迭代相比,这个额外检查的成本应该很小

L = ['ABC', 'HG', 'FL', '200', 'CP1']

df['text'] = df['text'].str.strip()
null = df['reference'].eq('')
df['updated'] = False

for item in L:
    ends = df['text'].str.endswith(item)
    diff = df['reference'].ne(item)

    m1 = ends & null & ~df['updated']
    m2 = ends & diff & ~null & ~df['updated']

    df.loc[m1, 'result'] = item
    df.loc[m2, 'result'] = 'wrong item'

    df.loc[m1 | m2, 'updated'] = True
结果:

    No    text reference      result updated
0  123  60 ABC       ABC               False
1  234    1nHG        HG               False
2  345   KL HG        FL  wrong item    True
3  456   21ABC                   ABC    True
4  567   K 200       200               False
5  678   1g HG                    HG    True

您可以删除最后一列,但可能会发现它对其他用途有用。

请不要将ascii边框用于数据帧。相反,只需复制shell中格式化的数据帧。@Alex-希望这就是您所要求的谢谢!这样快多了。你看不到我不需要任何for循环的解决方案,对吗?因为在这一点上,我不能说我的列表将包含多少元素。到目前为止已经有几百个了,但肯定还会有更多的。@MaMo,我看不到任何明显的东西。请随时将此问题保留一段时间。其他人可能会想出更聪明的方法!
    No    text reference      result updated
0  123  60 ABC       ABC               False
1  234    1nHG        HG               False
2  345   KL HG        FL  wrong item    True
3  456   21ABC                   ABC    True
4  567   K 200       200               False
5  678   1g HG                    HG    True