Как извлечь числа и строки из нескольких строк в столбце фрейма данных? - PullRequest
1 голос
/ 18 апреля 2019

DF1

index|Number
0    |[Number 1]
1    |[Number 2]
2    |[kg]
3    |[]
4    |[kg,Number 3]

В моем кадре данных в столбце Number мне нужно извлечь число, если оно присутствует, kg, если строка имеет kg и NaN если нет значения.Если в строке есть как число, так и kg, я извлеку только число.

Ожидаемый результат

index|Number
0    |1
1    |2
2    |kg
3    |NaN
4    |3

Я написал лямбда-функцию для этого, ноЯ получаю ошибку

NumorKG = lambda x: x.str.extract('(\d+)') if x.str.extract('(\d+)').isdigit() else 'kg' if x.str.find('kg') else "NaN"

DF1['Number']=DF1['Number'].apply(NumorKG)

Я получаю ошибку:

AttributeError: 'str' object has no attribute 'str'

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Используйте numpy.where для установленных значений:

#extract numeric to Series
d = df['Number'].str.extract('(\d+)', expand=False)
#test if digit
mask1 = d.str.isdigit().fillna(False)

# проверка, если значения содержат кг mask2 = df ['Number']. str.contains ('kg', na = False)

df['Number'] = np.where(mask1, d, 
               np.where(mask2 & ~mask1, 'kg',np.nan))
print (df)
  Number
0      1
1      2
2     kg
3    nan
4      3

Ваше решение должно быть изменено:

import re

def NumorKG(x):
    a = re.findall('(\d+)', x)
    if len(a) > 0:
        return a[0]
    elif 'kg' in x:
        return 'kg'

    else:
        return np.nan

df['Number']=df['Number'].apply(NumorKG)
print (df)
  Number
0      1
1      2
2     kg
3    NaN
4      3

И ваша лямбда-функция должна быть изменена:

NumorKG = lambda x: re.findall('(\d+)', x)[0] 
                    if len(re.findall('(\d+)', x)) > 0 
                    else 'kg' 
                    if 'kg' in x 
                    else np.nan
0 голосов
/ 18 апреля 2019

В apply возвращается скаляр, поэтому вы не можете использовать аксессор .str.

Поскольку вы имеете дело только с одним столбцом, вам не нужно подавать заявку.

В качестве альтернативы Jezrael (это было бы воспроизводимо), это возможное решение:

DF1 = pd.DataFrame({'Number': [["Number 1"], ["Number 2"], ["kg"], [""], ["kg", "Number 3"]]})
DF1['Number'] = DF1.Number.str.join(sep=" ")


mask_digit = DF1.Number.str.extract('(\d+)', expand=False).str.isdigit().fillna(False)
mask_kg = DF1['Number'].str.contains('kg', na=False)

DF1.loc[mask_digit, 'Number'] = DF1.Number.str.extract('(\d+)', expand=False)
DF1.loc[mask_kg,'Number'] = 'kg'
DF1.loc[~(mask_digit | mask_kg), 'Number'] = np.NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...