Замена пустых значений (пробел) на NaN в pandas
Я хочу найти все значения в кадре данных Pandas, которые содержат пробелы (любое произвольное количество) и заменить эти значения на NaN.
Есть идеи, как это можно улучшить?
В основном я хочу включить это:
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
Мне удалось сделать это с кодом ниже, но человек это уродливо. Это не Pythonic, и я уверен, что это не самое эффективное использование панд тоже. Я перебираю каждый столбец и выполняю логическую замену для маски столбца, созданной с помощью функции, которая выполняет поиск регулярных выражений для каждого значения, сопоставляя его с пробелами.
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()
, но было бы неплохо для полноты, если бы я мог вставить NaN
напрямую вместо None
.
Ответы
Ответ 1
Я думаю, что 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'))
# replace field that entirely space (or empty) with NaN
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)
если ваши действительные данные содержат пробелы.
Ответ 2
Если вы хотите заменить пустую строку и записи только пробелами, правильный ответ :!
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)
Тоже не работает - попробуй.
Ответ 3
Как насчет:
d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)
Функция applymap
применяет функцию к каждой ячейке информационного кадра.
Ответ 4
Я сделаю следующее:
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)
Вы можете удалить всю строку, а затем заменить пустую строку на np.nan
.
Ответ 5
Самое простое из всех решений:
df = df.replace(r'^\s+$', np.nan, regex=True)
Ответ 6
Если вы экспортируете данные из CSV файла, это может быть так просто:
df = pd.read_csv(file_csv, na_values=' ')
Это создаст фрейм данных, а также заменит пустые значения как Na
Ответ 7
Для очень быстрого и простого решения, где вы проверяете равенство по отношению к одному значению, вы можете использовать метод mask
.
df.mask(df == ' ')
Ответ 8
Вы также можете использовать фильтр, чтобы сделать это.
df = PD.DataFrame([
[-0.532681, 'foo', 0],
[1.490752, 'bar', 1],
[-1.387326, 'foo', 2],
[0.814772, 'baz', ' '],
[-0.222552, ' ', 4],
[-1.176781, 'qux', ' '])
df[df=='']='nan'
df=df.astype(float)
Ответ 9
print(df.isnull().sum()) # check numbers of null value in each column
modifiedDf=df.fillna("NaN") # Replace empty/null values with "NaN"
# modifiedDf = fd.dropna() # Remove rows with empty values
print(modifiedDf.isnull().sum()) # check numbers of null value in each column
Ответ 10
Это не элегантное решение, но, похоже, работает сохранение в XLSX, а затем его импорт обратно. Другие решения на этой странице не помогли мне, не знаю почему.
data.to_excel(filepath, index=False)
data = pd.read_excel(filepath)
Ответ 11
Все они близки к правильному ответу, но я бы не сказал, что это решит проблему, оставаясь наиболее читабельным для других, читающих ваш код. Я бы сказал, что ответ - это комбинация ответа BrenBarn и комментария tuomasttik под этим ответом. В ответе BrenBarn используется встроенная isspace
, но он не поддерживает удаление пустых строк, как было запрошено в OP, и я бы отнес это к стандартному isspace
замены строк нулем.
Я переписал его с помощью .apply
, чтобы вы могли вызывать его на pd.Series
или pd.DataFrame
.
Python 3:
Чтобы заменить пустые строки или строки полностью пробелов:
df = df.apply(lambda x: np.nan if isinstance(x, str) and (x.isspace() or not x) else x)
Чтобы заменить строки полностью пробелов:
df = df.apply(lambda x: np.nan if isinstance(x, str) and x.isspace() else x)
Чтобы использовать это в Python 2, вам нужно заменить str
на basestring
.
Python 2:
Чтобы заменить пустые строки или строки полностью пробелов:
df = df.apply(lambda x: np.nan if isinstance(x, basestring) and (x.isspace() or not x) else x)
Чтобы заменить строки полностью пробелов:
df = df.apply(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)
Ответ 12
Я попробовал этот код, и он работал для меня:
df.applymap (лямбда x: "NaN", если x == "" иначе x)