Ao seleccionar uma única coluna a partir de uma trama de dados pandas (por exemplo df.iloc[:, 0]
, df['A']
, ou df.A
, etc), o vector resultante é automaticamente convertido a uma série em vez de uma trama de dados de uma única coluna. No entanto, estou escrevendo algumas funções que levam um DataFrame como argumento de entrada. Portanto, prefiro lidar com DataFrame de coluna única em vez de Series para que a função possa assumir, digamos, df.columns como acessível. Agora eu tenho que converter explicitamente a série em um DataFrame usando algo parecido pd.DataFrame(df.iloc[:, 0])
. Este não parece o método mais limpo. Existe uma maneira mais elegante de indexar de um DataFrame diretamente para que o resultado seja um DataFrame de coluna única em vez de Series?
99
Respostas:
Como @Jeff menciona, existem algumas maneiras de fazer isso, mas recomendo usar loc / iloc para ser mais explícito (e levantar erros no início, se estiver tentando algo ambíguo):
In [10]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 'B']) In [11]: df Out[11]: A B 0 1 2 1 3 4 In [12]: df[['A']] In [13]: df[[0]] In [14]: df.loc[:, ['A']] In [15]: df.iloc[:, [0]] Out[12-15]: # they all return the same thing: A 0 1 1 3
As duas últimas opções removem a ambigüidade no caso de nomes de colunas inteiras (precisamente por que loc / iloc foram criados). Por exemplo:
In [16]: df = pd.DataFrame([[1, 2], [3, 4]], columns=['A', 0]) In [17]: df Out[17]: A 0 0 1 2 1 3 4 In [18]: df[[0]] # ambiguous Out[18]: A 0 1 1 3
fonte
[]
torna o resultado um emDataFrame
vez de umSeries
, mas onde nos documentos do pandas esse tipo de sintaxe de indexação é discutido? Estou apenas tentando obter o nome "oficial" para esta técnica de indexação para que eu realmente entenda. THX!Como Andy Hayden recomenda, utilizar .iloc / .loc para indexar dataframe (coluna única) é o caminho a percorrer; outro ponto a ser observado é como expressar as posições do índice. Use marcadores / posições de índice listados enquanto especifica os valores dos argumentos a serem indexados como Dataframe; não fazer isso retornará um 'pandas.core.series.Series'
Entrada:
A_1 = train_data.loc[:,'Fraudster'] print('A_1 is of type', type(A_1)) A_2 = train_data.loc[:, ['Fraudster']] print('A_2 is of type', type(A_2)) A_3 = train_data.iloc[:,12] print('A_3 is of type', type(A_3)) A_4 = train_data.iloc[:,[12]] print('A_4 is of type', type(A_4))
Resultado:
A_1 is of type <class 'pandas.core.series.Series'> A_2 is of type <class 'pandas.core.frame.DataFrame'> A_3 is of type <class 'pandas.core.series.Series'> A_4 is of type <class 'pandas.core.frame.DataFrame'>
fonte
Você pode usar
df.iloc[:, 0:1]
, neste caso, o vetor resultante será aDataFrame
e não uma série.Como você pode ver:
fonte
Essas três abordagens foram mencionadas:
pd.DataFrame(df.loc[:, 'A']) # Approach of the original post df.loc[:,[['A']] # Approach 2 (note: use iloc for positional indexing) df[['A']] # Approach 3
pd.Series.to_frame () é outra abordagem.
Por ser um método, pode ser usado em situações em que a segunda e a terceira abordagens acima não se aplicam. Em particular, é útil ao aplicar algum método a uma coluna em seu dataframe e você deseja converter a saída em um dataframe em vez de uma série. Por exemplo, em um Notebook Jupyter, uma série não terá uma saída bonita, mas um dataframe terá.
# Basic use case: df['A'].to_frame() # Use case 2 (this will give you pretty output in a Jupyter Notebook): df['A'].describe().to_frame() # Use case 3: df['A'].str.strip().to_frame() # Use case 4: def some_function(num): ... df['A'].apply(some_function).to_frame()
fonte