Python Pandas-更换回路以提高效率
我有一个数据帧(df) 和一个包含元素的列表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
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