Замена пустых значений (пробелов) на NaN в pandas
Я хочу найти все значения в фрейме данных Pandas, которые содержат пробелы (любое произвольное количество) и заменить эти значения NaNs.
любые идеи, как это можно улучшить?
в основном я хочу повернуть это:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz
2000-01-05 -0.222552 4
2000-01-06 -1.176781 qux
в:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz NaN
2000-01-05 -0.222552 NaN 4
2000-01-06 -1.176781 qux NaN
мне удалось сделать это с помощью кода ниже, но человек это уродливо. Это не Питон, и я уверен, что это не самое эффективное использование панд. Я петли через каждый столбец и сделать логическое замена против маски столбца, созданной путем применения функции, которая выполняет поиск регулярных выражений каждого значения, совпадающего с пробелами.
for i in df.columns:
df[i][df[i].apply(lambda i: True if re.search('^s*$', str(i)) else False)]=None
он может быть оптимизирован немного, только повторяя поля, которые могут содержать пустые строки:
if df[i].dtype == np.dtype('object')
но это не лучше
и, наконец, этот код устанавливает целевые строки в None, который работает с функциями Pandas, такими как fillna(), но было бы неплохо для полноты, если бы я мог на самом деле вставить Нэн напрямую, чем не иметь никакого.
помогите!
9 ответов:
Я думаю
df.replace()
работает:df = pd.DataFrame([ [-0.532681, 'foo', 0], [1.490752, 'bar', 1], [-1.387326, 'foo', 2], [0.814772, 'baz', ' '], [-0.222552, ' ', 4], [-1.176781, 'qux', ' '], ], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06')) print df.replace(r'\s+', np.nan, regex=True)
выдает:
A B C 2000-01-01 -0.532681 foo 0 2000-01-02 1.490752 bar 1 2000-01-03 -1.387326 foo 2 2000-01-04 0.814772 baz NaN 2000-01-05 -0.222552 NaN 4 2000-01-06 -1.176781 qux NaN
как Темак указал на это, используйте
df.replace(r'^\s+$', np.nan, regex=True)
в случае, если ваши действительные данные содержат пробелы.
Как насчет:
d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)
The
если вы хотите заменить пустую строку и записи только пробелами, то правильный ответ!:
df = df.replace(r'^\s*$', np.nan, regex=True)
принятый ответ
df.replace(r'\s+', np.nan, regex=True)
не заменяет пустую строку!, вы можете попробовать себя с данным примером слегка обновленным:
df = pd.DataFrame([ [-0.532681, 'foo', 0], [1.490752, 'bar', 1], [-1.387326, 'fo o', 2], [0.814772, 'baz', ' '], [-0.222552, ' ', 4], [-1.176781, 'qux', ''], ], columns='A B C'.split(), index=pd.date_range('2000-01-01','2000-01-06'))
обратите внимание, что 'fo o' не заменяется на Nan, хотя он содержит пробел. Далее отметим, что простое:
df.replace(r'', np.NaN)
тоже не работает-попробуйте.
Я сделал так:
df = df.apply(lambda x: x.str.strip()).replace('', np.nan)
или
df = df.apply(lambda x: x.str.strip() if isinstance(x, str) else x).replace('', np.nan)
вы можете удалить все str, а затем заменить пустой str на
np.nan
.
Если вы экспортируете данные из файла CSV, это может быть так просто:
df = pd.read_csv(file_csv, na_values=' ')
это создаст фрейм данных, а также заменит пустые значения как Na
для очень быстрого и простого решения, где вы проверяете равенство против одного значения, вы можете использовать
mask
метод.df.mask(df == ' ')