#python #pandas #for-loop #conditional #multiple-columns
#python #pandas #for-цикл #условные операторы #несколько столбцов
Вопрос:
У меня есть фрейм данных pandas, который содержит выглядит следующим образом:
A A_type
"Hello" String
15 Integer
"Hi" String
56.78 Float
Я хочу создать третий столбец, который сообщает то же значение, что и A, если A имеет соответствующий элемент «A_type» с именем «String», в противном случае выведите «пустой». Столбец будет выглядеть следующим образом:
B
"Hello"
"blank"
"Hi"
"blank"
Я попытался сделать что-то вроде:
df['B'] = df['A']
for j in df['A_type']:
for i in df['B']:
if j == "String":
i = i
else:
i = "blank"
Есть ли какой-либо более эффективный подход к такой проблеме, который может помочь мне избежать всех этих циклов for?
Заранее большое спасибо
Ответ №1:
Используйте Series.where
or Series.mask
с инвертированным условием или numpy.where
:
df['B'] = df['A'].where(df['A_type'] == "String", 'blank')
#df['B'] = df['A'].mask(df['A_type'] != "String", 'blank')
#alternative
#df['B'] = np.where(df['A_type'] == "String", df['A'], 'blank')
print (df)
A A_type B
0 Hello String Hello
1 15 Integer blank
2 Hi String Hi
3 56.78 Float blank
Ответ №2:
Также вы можете попробовать:
df['B'] = df.apply(lambda x: x['A'] if x['A_type'] == 'String' else "Blank", axis = 1)
Комментарии:
1. Не используйте apply, потому что циклы под капотом, особенно если существуют векторизованные альтернативы.
2. Потому что это медленно в больших фреймах данных
3. Хорошо, спасибо. Я попытаюсь изменить его, чтобы он соответствовал большому df.
Ответ №3:
df['B']=df['A'].copy()
df.loc[df['A_type']!="String", 'B'] = "blank"
O/P:
A A_type B
0 Hello String Hello
1 blank blank blank
2 Hi String Hi
3 blank blank blank
объяснение:
- Возьмите копию
Col A
- обновляйте значение только до того,
blank
гдеA_Type
его нетString
Комментарии:
1. @DebanjanB — Добавлено, спасибо за комментарий, я бы рассмотрел это в будущем 🙂