我有一个像 -
这样的数据框 FileName PageNo LineNo EntityName
1 17743633 - 1 TM000002 69 Ambuja Cement Limited
2 17743633 - 1 TM000003 14 Vessel Name
3 17743633 - 1 TM000003 12 tyre Chips (Shredded Tyres)
4 17743633 - 1 TM000006 22 ambuja Cement Limited
5 17743633 - 1 TM000006 28 Binani Cement Limited
我必须从EntityName列首字母为小写的数据框中删除这些行。即我必须保留以大写字母开头的值。
到目前为止,我已经习惯了方法 -
df['EntityName'] = map(lambda x: x[0].isupper(), df['EntityName'])
但是它给出了NaN值。
我尝试的另一件事是正则表达式。
df['EntityName'] = df['EntityName'].str.replace('^[a-z]+$','')
但是没有效果。
另一个是 -
qw = df.EntityName.str[0]
df = df[qw.isupper()]
但显示错误 -
'系列'对象没有属性' isupper'
有人可以向我推荐正确的代码段或任何类型的提示吗?
答案 0 :(得分:5)
首先通过索引选择第一个字母,然后选中isupper
或islower
并按boolean indexing
过滤:
df = df[df['EntityName'].str[0].str.isupper()]
#for working with NaN and None
#df = df[df['EntityName'].str[0].str.isupper().fillna(False)]
或者:
df = df[~df['EntityName'].str[0].str.islower()]
#for working with NaN and None
df = df[~df['EntityName'].str[0].str.islower().fillna(False)]
或者使用带有正则表达式的str.contains
- ^
用于匹配字符串的第一个值:
df = df[df['EntityName'].str.contains('^[A-Z]+')]
如果数据中没有NaN
是列表理解,则解决方法:
df = df[[x[0].isupper() for x in df['EntityName']]]
使用空字符串和NaN
的更常规解决方案是添加if-else
:
mask = [x[0].isupper() if isinstance(x,str) and len(x)>0 else False for x in df['EntityName']]
df = df[mask]
print (df)
FileName ... EntityName
1 17743633 - 1 ... Ambuja Cement Limited
2 17743633 - 1 ... Vessel Name
5 17743633 - 1 ... Binani Cement Limited
答案 1 :(得分:2)
您可以使用:
df[df.EntityName.str[0].str.isupper()]
答案 2 :(得分:2)
查看数据我认为istitle
会做你的工作,即
df[df['EntityName'].str.istitle()]
FileName PageNo LineNo EntityName
1 17743633 - 1 TM000002 69 Ambuja Cement Limited
2 17743633 - 1 TM000003 14 Vessel Name
5 17743633 - 1 TM000006 28 Binani Cement Limited
答案 3 :(得分:0)
为了提高性能,请考虑使用简单的列表推导进行索引并访问系列的numpy
数组表示:
df = df[[i[0].isupper() for i in df['EntityName'].values]]
如果您不希望系列中出现任何空字符串,则此解决方案将起作用。
效果基准
from operator import itemgetter, methodcaller
s = pd.Series(['Hello', 'hello', 'test', 'Test'])
def jpp(s):
return list(map(methodcaller('isupper'), map(itemgetter(0), s.values)))
def jpp2(s):
return [i[0].isupper() for i in s.values]
def jez(s):
return s.str[0].str.isupper()
s = pd.concat([s]*100000)
%timeit jpp(s) # 116 ms per loop
%timeit jpp2(s) # 82 ms per loop
%timeit jez(s) # 313 ms per loop