考虑这段代码:
from StringIO import StringIO
import pandas as pd
txt = """a, RR
10, 1asas
20, 1asasas
30,
40, asas
50, ayty
60, 2asas
80, 3asas"""
frame = pd.read_csv(StringIO(txt), skipinitialspace=True)
print frame,"\n\n\n"
l=[]
for i,j in frame[~ frame['RR'].str.startswith("1", na=True)]['RR'].iteritems():
if j.startswith(('2','3')):
if frame[frame['RR'].str.startswith("1", na=False)]['RR'].str.match("1"+j[1:], as_indexer = True).any():
l.append(i)
else:
if frame[frame['RR'].str.startswith("1", na=False)]['RR'].str.match("1"+j, as_indexer = True).any():
l.append(i)
frame = frame.drop(frame.index[l])
print frame
我在这里做的是,
循环数据帧以删除数据帧中已经具有
RR
的任何 1RR
如果
RR
在 start 处具有 2 or 3
,则如果 RR
在数据框中具有 1RR[1:]
,则删除。
如果
RR
以 1
开头或者是 NaN
,请勿触摸它。
代码工作正常,但是这个
dataframe
将有多达 100 万个条目,我认为这段代码没有经过优化。由于我刚刚开始pandas
,我的知识有限。
有没有什么方法可以在没有iteration
的情况下实现这一目标。 pandas
有任何内置实用程序可以执行此操作吗?
首先,保留所有以
1
或 nan
: 开头的字符串
keep = frame['RR'].str.startswith("1", na=True)
keep1 = keep[keep] # will be used at the end
第二,保留以
2
或 3
开头且不在第一个数据帧中的字符串 rr1
:
rr1 = frame.loc[frame['RR'].str.startswith("1", na=False), 'RR']
keep2 = ~frame.loc[
(frame['RR'].str.startswith("2")) | (frame['RR'].str.startswith("3")), 'RR'
].str.slice(1).isin(rr1.str.slice(1))
第三,添加前导
rr1
后保留1
中没有的其他字符串:
import numpy as np
keep3 = ~("1" + frame.loc[
~frame['RR'].str.slice(0,1).isin([np.nan, "1", "2", "3"]), 'RR'
]).isin(rr1)
最后,把所有东西放在一起:
frame[pd.concat([keep1, keep2, keep3]).sort_index()]