Я пытаюсь переключить значения между столбцами Range
и Unit
в приведенном ниже фрейме данных при условии, что если Unit содержит -
, то замените Unit
на Range
и Range
на Unit
. Для этого я создаю столбец unit_backup
, чтобы не потерять исходное значение Unit
.
1. фрейм данных
sample_df = pd.DataFrame({'Range':['34-67',12,'gm','45-90'],
'Unit':['ml','35-50','10-100','mg']})
sample_df
Range Unit
0 34-67 ml
1 12 35-50
2 gm 10-100
3 45-90 mg
2. Функция Ниже приведен код, который я пробовал, но получаю сообщение об ошибке:
def range_unit_correction_fn(df):
# creating backup of Unit column
df['unit_backup'] = df['Unit']
# condition check
if df['unit_backup'].str.contains("-"):
# if condition is True then replace `Unit` value with `Range` and `Range` with `unit_backup`
df['Unit'] = df['Range']
df['Range'] = df['unit_backup']
else:
# if condition False then keep the same value
df['Range'] = df['Range']
# drop the backup column
df = df.drop(['unit_backup'],axis=1)
return df
sample_df = sample_df.apply(range_unit_correction_fn, axis=1)
sample_df
Ошибка:
1061 def apply_standard(self):
1062 if self.engine == "python":
-> 1063 results, res_index = self.apply_series_generator()
...
----> 4 if df['unit_backup'].str.contains("-"):
5 df['Unit'] = df['Range']
6 df['Range'] = df['unit_backup']
AttributeError: 'str' object has no attribute 'str'
Это кажется какой-то глупой ошибкой, но я не уверен, где я ошибаюсь.
Цените любую помощь здесь.
@Бармар Я знаю np.where()
, но не pd.where()
. Но все же попробовал и получил эту ошибку: AttributeError: module 'pandas' has no attribute 'where'
Не использую np.where
, так как не хочу использовать другую библиотеку.
Извините, это была опечатка, я имел в виду np.where()
, который можно использовать с pandas df.
@Barmar .. конечно, без проблем :)
Когда вы получаете доступ к df['unit_backup']
, вы получаете скалярное строковое значение, а не серию pandas, поэтому вызов .str
по нему вызывает ошибку.
Чтобы исправить это, вы можете проверить условие непосредственно на строковом значении построчно:
def range_unit_correction_fn(df):
# creating backup of Unit column
df['unit_backup'] = df['Unit']
# condition check
if '-' in df['unit_backup']:
# if condition is True then replace `Unit` value with `Range` and `Range` with `unit_backup`
df['Unit'] = df['Range']
df['Range'] = df['unit_backup']
# drop the backup column
df = df.drop(['unit_backup'])
return df
Прочитав текст вашего ответа, я понял свою ошибку. Большое спасибо. Очень ценю вашу помощь.
В качестве альтернативы, в одной строке, без необходимости временного столбца или «резервной копии» столбца:
sample_df[['Range', 'Unit']] = sample_df[['Unit', 'Range']].where(sample_df['Unit'].str.contains('-'), sample_df[['Range', 'Unit']].values)
что дает:
Range Unit
0 34-67 ml
1 35-50 12
2 10-100 gm
3 45-90 mg
Вау.. это действительно впечатляет. Я понятия не имел, что это можно сделать таким образом. Спасибо, что показали этот альтернативный способ. Ценю вашу помощь!!!
Используйте
pd.where()
, чтобы ограничить операции определенными строками.