#python #pandas #dataframe
#питон #панды #фрейм данных
Вопрос:
У меня есть фрейм данных, который выглядит следующим образом (на самом деле намного больше):
df = pd.DataFrame([ [-0.531, '30 mg', 0], [1.49, '70 kg', 1], [-1.3826, 'food delivery', 2], [0.814, '80 degrees', ' '], [-0.22, ' ', 4], [-1.11, '70 %', ' '], ], columns='Power Value Stage'.split(), index=pd.date_range('2000-01-01','2000-01-06'))
Теперь я добавляю новый столбец с именем Unit в фрейм данных, который фактически разделяет значение столбца. Тем не менее, кажется, что он буквально разделяет все, даже если значения не имеют смысла. Например, такие ценности, как доставка еды, не нужно разделять.
Я хочу, чтобы значения разделялись только в том случае, если str[0]
это цифра AND
, если str[1]
это Я думаю, что я действительно близок, однако я застрял. Это мой код:
df['Unit'] = df['Value'].str.extract(r'd*%s*(w{,5})b').fillna('')[0]
Это мой желаемый результат, когда я выполняю печать(df):
Power Value Stage Unit 2000-01-01 -0.5310 30 mg 0 mg 2000-01-02 1.4900 70 kg 1 kg 2000-01-03 -1.3826 food delivery 2 2000-01-04 0.8140 80 degrees 2000-01-05 -0.2200 4 2000-01-06 -1.1100 70 % %
Это мой текущий вывод(похоже, он не содержит знака%):
Power Value Stage Unit 2000-01-01 -0.5310 30 mg 0 2000-01-02 1.4900 70 kg 1 2000-01-03 -1.3826 food delivery 2 2000-01-04 0.8140 80 degrees 2000-01-05 -0.2200 4 2000-01-06 -1.1100 70 %
Ответ №1:
У меня есть обходной путь без использования регулярных выражений:
idx = (df['Value'].str.len() lt;= 5) amp; df['Value'].str[0].str.isdecimal() df.loc[idx, 'Unit'] = df.loc[idx, 'Value'].str.split().str[-1]
Power Value Stage Unit 2000-01-01 -0.5310 30 mg 0 mg 2000-01-02 1.4900 70 kg 1 kg 2000-01-03 -1.3826 food delivery 2 NaN 2000-01-04 0.8140 80 degrees NaN 2000-01-05 -0.2200 4 NaN 2000-01-06 -1.1100 70 % %
Возможно, вы захотите заполнить НаН позже.
Ответ №2:
Что касается меня, то все гораздо проще. if/else
В этом случае напишите функцию на основе, а не используйте регулярные выражения. Ты можешь сделать это вот так:
def is_digit(s): try: float(s.replace(',', '.')) return True except ValueError: return False def extract_unit(s): s = re.sub(' ', ' ', s).strip() s = s.split(' ') dig, unit = s[0], s[1] return unit if is_digit(dig) and len(unit) lt;= 5 else None df['Unit'] = df['Value'].map(extract_unit)