Создайте новый форматированный столбец в Pandas, используя другой столбец

#python #pandas #lambda

#python #pandas #лямбда

Вопрос:

У меня есть следующий набор данных в фрейме данных pandas:

 I219
F03
C449
C189
  

Мне нужно создать новый столбец, в котором, если длина ячейки равна 4, то после третьего символа должна быть точка, подобная этой:

 I21.9
F03
C44.9
C18.9
  

Покопавшись в StackOverflow, я придумал это лямбда-выражение, но, похоже, я не могу заставить это работать.

 df['UNDERLYINGCAUSE_TEST'] = df.UNDERLYINGCAUSE.apply(lambda x: x if len(x) == 4 else x[0:3]   '.'   x[3:])
  

Ошибка, которую я получаю, это «тип объекта «float» как нет len ()». Не уверен, откуда это взялось, поскольку у меня нет значений с плавающей запятой в этом столбце.

Ответ №1:

Вы были почти на месте. Ваша лямбда-функция выполняет прямо противоположное тому, что вы хотели, потому что форматирование было неправильным. Кроме того, вы можете преобразовать столбец dtype в объект с astype(str) помощью . Попробуйте это:

 df['UNDERLYINGCAUSE_TEST'] = df.UNDERLYINGCAUSE.astype(str).apply(lambda x: x[0:3]   '.'   x[3:] if len(x) == 4 else x )
  

В качестве альтернативы, поскольку вы имеете дело с манипулированием столбцами / рядами, вы можете использовать map вместо apply , что быстрее и эффективнее при манипулировании столбцами.

 df['UNDERLYINGCAUSE_TEST'] = df.UNDERLYINGCAUSE.astype(str).map(lambda x: x[0:3]   '.'   x[3:] if len(x) == 4 else x )
  

Вывод:

   UNDERLYINGCAUSE UNDERLYINGCAUSE_TEST
0            I219                I21.9
1             F03                  F03
2            C449                C44.9
3            C189                C18.9
  

Комментарии:

1. В итоге я выяснил свою ошибку ID10T с моим ответом, но я также дам вам шанс.

2. Конечно, хотелось бы знать, работает ли это для вас. Просто как предложение, работать с map always лучше, если нужно просто манипулировать одним столбцом.

3. Просто попробовал ваш ответ, и он тоже работает. Мне нужно будет запомнить подсказку map на будущее. Спасибо!

4. Рад, что это помогает. Было бы неплохо, если бы вы могли проголосовать за ответ. Чтобы люди видели, что это работает.

Ответ №2:

Понял мою ошибку. Мне нужно было поместить мой x в str() для моего оператора if.

 df['UNDERLYINGCAUSE_TEST'] = df.UNDERLYINGCAUSE.apply(lambda x: x if len(str(x)) < 4 else x[0:3]   '.'   x[3:])
  

Ответ №3:

Кажется, что результаты тернарного оператора должны быть наоборот. Чтобы убедиться, что тип столбца — string, вы можете изменить его перед применением lambda:

 df['UNDERLYINGCAUSE_TEST'] = df['UNDERLYINGCAUSE_TEST'].astype(str)
df['UNDERLYINGCAUSE_TEST'] = df['UNDERLYINGCAUSE_TEST'].apply(lambda x: x[0:3]   '.'   x[3:] if len(x) == 4 else x)
  

Ответ №4:

Другой ответ правильный, но вот альтернативы. Для дальнейшего использования вы можете получить доступ к строкам Series с Series.str помощью метода

 df = {'c':['I219','F03','C449','C189']}
df['new_c'] = df.c.str[:3]   '.'   df.c.str[3:]
df.loc[df['new_c'].isna(), 'new_c'] = df.loc[df['new_c'].isna(), 'c']

df['new_c2'] = df.c.apply(lambda x: x if len(x) < 4 else x[0:3]   '.'   x[3:])