Удаление строк из информационного кадра, первая буква которого в нижнем регистре - PullRequest
0 голосов
/ 30 мая 2018

У меня есть такой фрейм данных -

    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.

другоея попробовал regex.

df['EntityName'] = df['EntityName'].str.replace('^[a-z]+$','')

, но он не показывает никакого эффекта.

другой был -

qw = df.EntityName.str[0]
df = df[qw.isupper()]

, но он показывает ошибку -

Объект 'Series' не имеет атрибута 'isupper'

Может кто-нибудь подсказать мне правильный фрагмент кода или какой-либо намек?

Ответы [ 4 ]

0 голосов
/ 30 мая 2018

Глядя на данные, я думаю, 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
0 голосов
/ 30 мая 2018

Вы можете использовать:

df[df.EntityName.str[0].str.isupper()]
0 голосов
/ 30 мая 2018

Для повышения производительности рассмотрите возможность индексирования с помощью простого понимания списка и доступа к представлению массива 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
0 голосов
/ 30 мая 2018

Сначала выберите первую букву с помощью индексации, а затем отметьте 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 s в данных - это понимание списка:

df = df[[x[0].isupper() for x in df['EntityName']]]

Более общее решение для работы с пустыми строками и NaN s это добавление 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...