#python #regex #pandas #null #fillna
#python #регулярное выражение #pandas #null #заполните
Вопрос:
У меня есть странный столбец с именем null
в dataframe, который содержит некоторые пропущенные значения из других столбцов. Один столбец — это координаты широты с именем location
, другой — целое число, представляющее целевую переменную с именем level
. В некоторых, но не во всех случаях, когда location
или level
имеют пропущенные значения, значения, которые должны быть там, находятся в этом null
столбце. Вот пример df:
pd.DataFrame(
{'null': {0: '43.70477575,-72.28844073', 1: '2', 2: '43.70637091,-72.28704334', 3: '4', 4: '3'},
'location': {0: nan, 1: nan, 2: nan, 3: nan, 4: nan},
'level': {0: nan, 1: nan, 2: nan, 3: nan, 4: nan}
}
)
Мне нужно иметь возможность фильтровать null
столбец в соответствии с тем, является ли значение целым числом или строкой, а затем на основе этого заполнить пропущенное значение в соответствующем столбце соответствующим значением. Я пытался использовать .apply()
с функцией лямбда, а также .match()
, .contains()
и in
внутри цикла for, но пока безуспешно.
Комментарии:
1. каков ваш ожидаемый результат
2. Мне нужно иметь возможность фильтровать столбец null в зависимости от того, является ли значение целым числом или строкой, а затем, основываясь на этом, заполните его для пропущенного значения в соответствующем столбце (строки в ‘location’ и целые числа в ‘level’).
3. Проверьте мой ответ, дайте мне знать, работает ли он ~
Ответ №1:
Самый простой, если не самый простой подход, это просто заполнить все пропущенные значения в df.location
и df.level
значениями в df.null
, затем создать логический фильтр с регулярным выражением, чтобы возвращать неподходящие / неправильно назначенные значения в df.location
и df.level
в np.nan
.
pd.fillna()
df = pd.DataFrame(
{'null': {0: '43.70477575,-72.28844073', 1: '2', 2: '43.70637091,-72.28704334', 3: '4', 4: '3'},
'location': {0: nan, 1: nan, 2: nan, 3: nan, 4: nan},
'level': {0: nan, 1: nan, 2: nan, 3: nan, 4: nan}
}
)
for col in ['location', 'level']:
df[col].fillna(
value = stress.null,
inplace = True
)
Теперь мы будем использовать строковые выражения для исправления неправильно присвоенных значений.
str.contains()
# Converting columns to type str so string methods work
df = df.astype(str)
# Using regex to change values that don't belong in column to NaN
regex = '[,]'
df.loc[df.level.str.contains(regex), 'level'] = np.nan
regex = '^d.?0?$'
df.loc[df.location.str.contains(regex), 'location'] = np.nan
# Returning `df.level` to float datatype (str is the correct
# datatype for `df.location`
df.level.astype(float)
Вот результат:
pd.DataFrame(
{'null': {0: '43.70477575,-72.28844073', 1: '2', 2: '43.70637091,-72.28704334', 3: '4', 4: '3'},
'location': {0: '43.70477575,-72.28844073', 1: nan, 2: '43.70637091,-72.28704334', 3: nan, 4: nan},
'level': {0: nan, 1: '2', 2: nan, 3: '4', 4: '3'}
}
)
Ответ №2:
Давайте попробуем to_numeric
checker = pd.to_numeric(df.null, errors='coerce')
checker
Out[171]:
0 NaN
1 2.0
2 NaN
3 4.0
4 3.0
Name: null, dtype: float64
И примените, isnull
если возврат NaN
означает, что это строка, а не int
isstring = checker.isnull()
Out[172]:
0 True
1 False
2 True
3 False
4 False
Name: null, dtype: bool
# isnumber = checker.notnull()
Заполните значение
df.loc[isnumber, 'location'] = df['null']
df.loc[isstring, 'level'] = df['null']
Комментарии:
1. Этот код может фильтровать столбец null для целых чисел, но он не заполняет пропущенные значения в столбце level этими значениями.
2. @KristianCanler вы можете заполнить вышеуказанное условие, также проверьте обновление
Ответ №3:
Другой подход может использовать метод pandas.Series.mask
:
>>> df
null location level
0 43.70477575,-72.28844073 NaN NaN
1 2 NaN NaN
2 43.70637091,-72.28704334 NaN NaN
3 4 NaN NaN
4 3 NaN NaN
>>> df.level.mask(df.null.str.isnumeric(), other = df.null, inplace = True)
>>> df.location.where(df.null.str.isnumeric(), other = df.null, inplace = True)
>>>
>>> df
null location level
0 43.70477575,-72.28844073 43.70477575,-72.28844073 NaN
1 2 NaN 2
2 43.70637091,-72.28704334 43.70637091,-72.28704334 NaN
3 4 NaN 4
4 3 NaN 3
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas .Series.mask.html
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas .Series.where.html
Комментарии:
1. Извините, мне нужно было обновить фрейм данных! Это была отредактированная версия. Теперь у меня есть правильное значение в OP.
2. Когда я реализую этот код, кажется, что он заполняет некоторые строки в df.level, которые должны быть целыми числами.