Quero encontrar todos os valores em um quadro de dados do Pandas que contenham espaço em branco (qualquer quantidade arbitrária) e substituir esses valores por NaNs.
Alguma idéia de como isso pode ser melhorado?
Basicamente, quero transformar isso:
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
Nisso:
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
Consegui fazer isso com o código abaixo, mas cara, é feio. Não é Pythonic e tenho certeza que também não é o uso mais eficiente de pandas. Eu percorro cada coluna e faço a substituição booleana de uma máscara de coluna gerada aplicando uma função que faz uma pesquisa regex de cada valor, correspondendo no espaço em branco.
for i in df.columns:
df[i][df[i].apply(lambda i: True if re.search('^\s*$', str(i)) else False)]=None
Ele pode ser otimizado um pouco, apenas repetindo os campos que podem conter cadeias vazias:
if df[i].dtype == np.dtype('object')
Mas isso não melhora muito
E, finalmente, esse código define as seqüências de destino como None, que funciona com as funções do Pandas fillna()
, mas seria ótimo se eu pudesse inserir um NaN
diretamente em vez de None
.
replace
com uma regex ... (talvez isso deva ser solicitado como um recurso).Respostas:
Eu acho que
df.replace()
faz o trabalho, já que os pandas 0,13 :Produz:
Como Temak apontou, use
df.replace(r'^\s+$', np.nan, regex=True)
caso seus dados válidos contenham espaços em branco.fonte
pd.Series(["1", "#", "9", " .", None]).replace(r"( +\.)|#", "X", regex=True).values
que dá['1', 'X', '9', 'X', None]
df.replace(r'^\s+$', np.nan, regex=True)
Se você deseja substituir uma sequência e registros vazios por apenas espaços, a resposta correta é !
A resposta aceita
Não substitui uma string vazia !, você pode tentar o mesmo exemplo ligeiramente atualizado:
Observe também que 'fo o' não é substituído por Nan, embora contenha um espaço. Nota adicional, que um simples:
Também não funciona - experimente.
fonte
E se:
A
applymap
função aplica uma função a todas as células do quadro de dados.fonte
isinstance
será um pouco mais rápido.''
. Para considerar também cadeias vazias, use:d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and (not x or x.isspace()) else x)
Eu vou fazer isso:
ou
Você pode remover todos os str e substituir str vazio por
np.nan
.fonte
Mais simples de todas as soluções:
fonte
Se você estiver exportando os dados do arquivo CSV, pode ser tão simples quanto isto:
Isso criará o quadro de dados e substituirá os valores em branco como Na
fonte
skipinitialspace=True
também remove qualquer espaço em branco após o delimitador, o que causaria qualquer comprimento de espaço em branco, como cadeias de caracteres vaziasnan
. No entanto, se você deseja manter os espaços iniciais por qualquer motivo, essa opção não é uma boa escolha.Para uma solução muito rápida e simples em que você verifica a igualdade em relação a um único valor, você pode usar o
mask
métodofonte
Tudo isso é quase a resposta certa, mas eu não diria que resolveria o problema, permanecendo mais legível para outras pessoas que lêem seu código. Eu diria que a resposta é uma combinação da resposta de BrenBarn e do comentário de tuomasttik abaixo dessa resposta . A resposta de BrenBarn utiliza o
isspace
builtin, mas não suporta a remoção de cadeias vazias, conforme solicitado pelo OP, e eu tenderia a atribuir isso como o caso de uso padrão da substituição de cadeias por nulas.Eu o reescrevi com
.apply
, para que você possa chamá-lo em umpd.Series
oupd.DataFrame
.Python 3:
Para substituir cadeias vazias ou cadeias de espaços inteiramente:
Para substituir seqüências de caracteres de espaços inteiramente:
Para usar isso no Python 2, você precisará substituir
str
porbasestring
.Python 2:
Para substituir cadeias vazias ou cadeias de espaços inteiramente:
Para substituir seqüências de caracteres de espaços inteiramente:
fonte
Isso funcionou para mim. Quando importo meu arquivo csv, adicionei na_values = ''. Os espaços não estão incluídos nos valores padrão de NaN.
df = pd.read_csv (caminho do arquivo, na_values = '')
fonte
você também pode usar um filtro para fazer isso.
fonte
fonte
Essa não é uma solução elegante, mas o que parece funcionar está salvando no XLSX e depois importando-o de volta. As outras soluções nesta página não funcionaram para mim, não sei por quê.
fonte