Qual é a maneira mais fácil de remover colunas duplicadas de um dataframe?
Estou lendo um arquivo de texto com colunas duplicadas por meio de:
import pandas as pd
df=pd.read_table(fname)
Os nomes das colunas são:
Time, Time Relative, N2, Time, Time Relative, H2, etc...
Todas as colunas Tempo e Relativo ao tempo contêm os mesmos dados. Eu quero:
Time, Time Relative, N2, H2
Todas as minhas tentativas de descartar, excluir, etc., como:
df=df.T.drop_duplicates().T
Resultar em erros de índice com valor exclusivo:
Reindexing only valid with uniquely valued index objects
Desculpe por ser um Pandas noob. Qualquer sugestão seria apreciada.
detalhes adicionais
Versão do Pandas: 0.9.0
Versão do Python: 2.7.3
Windows 7
(instalado via Pythonxy 2.7.3.0)
arquivo de dados (nota: no arquivo real, as colunas são separadas por tabulações, aqui são separadas por 4 espaços):
Time Time Relative [s] N2[%] Time Time Relative [s] H2[ppm]
2/12/2013 9:20:55 AM 6.177 9.99268e+001 2/12/2013 9:20:55 AM 6.177 3.216293e-005
2/12/2013 9:21:06 AM 17.689 9.99296e+001 2/12/2013 9:21:06 AM 17.689 3.841667e-005
2/12/2013 9:21:18 AM 29.186 9.992954e+001 2/12/2013 9:21:18 AM 29.186 3.880365e-005
... etc ...
2/12/2013 2:12:44 PM 17515.269 9.991756+001 2/12/2013 2:12:44 PM 17515.269 2.800279e-005
2/12/2013 2:12:55 PM 17526.769 9.991754e+001 2/12/2013 2:12:55 PM 17526.769 2.880386e-005
2/12/2013 2:13:07 PM 17538.273 9.991797e+001 2/12/2013 2:13:07 PM 17538.273 3.131447e-005
import pandas as pd; pd.__version__
)read_table
para o exemplo que criei.Respostas:
Existe uma solução de uma linha para o problema. Isso se aplica se alguns nomes de coluna estiverem duplicados e você desejar removê-los:
Como funciona:
Suponha que as colunas do quadro de dados sejam
['alpha','beta','alpha']
df.columns.duplicated()
retorna uma matriz booleana: aTrue
ouFalse
para cada coluna. Se forFalse
, o nome da coluna será exclusivo até esse ponto; se forTrue
, o nome da coluna será duplicado anteriormente. Por exemplo, usando o exemplo fornecido, o valor retornado seria[False,False,True]
.Pandas
permite indexar usando valores booleanos em que seleciona apenas osTrue
valores. Uma vez que queremos manter as colunas não duplicadas, precisamos que o array booleano acima seja invertido (ou seja[True, True, False] = ~[False,False,True]
)Por fim,
df.loc[:,[True,True,False]]
seleciona apenas as colunas não duplicadas usando o recurso de indexação mencionado anteriormente.Nota : o acima verifica apenas nomes de colunas, não valores de coluna.
fonte
df.T.drop_duplicates().T
.Parece que você já conhece os nomes exclusivos das colunas. Se for esse o caso, então
df = df['Time', 'Time Relative', 'N2']
funcionaria.Caso contrário, sua solução deve funcionar:
Você provavelmente tem algo específico para seus dados que está bagunçando tudo. Poderíamos fornecer mais ajuda se você pudesse fornecer mais detalhes sobre os dados.
Edit: Como Andy disse, o problema é provavelmente com os títulos das colunas duplicados.
Para um arquivo de tabela de amostra 'dummy.csv' eu criei:
usando
read_table
fornece colunas exclusivas e funciona corretamente:Se sua versão não permitir, você pode criar juntos uma solução para torná-los únicos:
fonte
df['Time']
seleciona todas as séries temporais (ou seja, retorna um DataFrame), edf['Time', ..]
isso retornará todo o DataFrame.RecursionError: maximum recursion depth exceeded
A transposição é ineficiente para grandes DataFrames. Aqui está uma alternativa:
Use-o assim:
Editar
Uma versão com uso eficiente de memória que trata nans como qualquer outro valor:
fonte
my_df.T.drop_duplicates().T
seria suspenso em grandes dataframes./usr/local/lib/python3.5/dist-packages/ipykernel_launcher.py:17: DeprecationWarning: 'pandas.core.common.array_equivalent' is deprecated and is no longer public API
if array_equivalent(ia, ja):
porif np.array_equal(ia, ja):
parece produzir os mesmos resultados, mas li que ele não lida bem com NaNs.array_equivalent
ainda está disponível no repositório público, possivelmente em um branch mais antigo?numpy.array_equiv
; para pandas, não vejo nenhum branch de lançamento anterior no GitHub,pandas.core.common
mas talvez haja outros lugares para procurarSe não me engano, o seguinte faz o que foi pedido sem os problemas de memória da solução de transposição e com menos linhas que a função de @kalu, mantendo a primeira de quaisquer colunas com nome semelhante.
fonte
Parece que você está no caminho certo. Aqui está o one-liner que você estava procurando:
Mas, como não existe um quadro de dados de exemplo que produza a mensagem de erro referenciada
Reindexing only valid with uniquely valued index objects
, é difícil dizer exatamente o que resolveria o problema. se restaurar o índice original for importante para você, faça o seguinte:fonte
Primeiro passo: - Leia a primeira linha, ou seja, todas as colunas e remova todas as colunas duplicadas.
Segunda etapa: - Finalmente, leia apenas as colunas.
fonte
Corri para este problema onde o forro fornecido pela primeira resposta funcionou bem. No entanto, tive a complicação extra em que a segunda cópia da coluna tinha todos os dados. A primeira cópia não.
A solução foi criar dois quadros de dados dividindo um quadro de dados alternando o operador de negação. Depois de ter os dois quadros de dados, executei uma instrução de junção usando o
lsuffix
. Dessa forma, eu poderia fazer referência e excluir a coluna sem os dados.- E
fonte
A maneira abaixo identificará colunas falsas para revisar o que está errado ao construir o dataframe originalmente.
fonte
Maneira rápida e fácil de eliminar as colunas duplicadas por seus valores:
df = df.T.drop_duplicates (). T
Mais informações: Pandas DataFrame drop_duplicates manual .
fonte