Python Pandas:将选定的列保留为DataFrame而不是Series


99

从pandas DataFrame中选择单个列时(例如df.iloc[:, 0]df['A']df.A等),结果矢量将自动转换为Series而不是单列DataFrame。但是,我正在编写一些将DataFrame作为输入参数的函数。因此,我更喜欢处理单列DataFrame而不是Series,以便函数可以假定df.columns是可访问的。现在,我必须使用来将Series显式转换为DataFrame pd.DataFrame(df.iloc[:, 0])。这似乎不是最干净的方法。是否有更优雅的方法直接从DataFrame进行索引,以便结果是单列DataFrame而不是Series?


6
df.iloc [:,[0]]或df [['A']]; df.A仅会退还一系列
杰夫(Jeff)

Answers:


104

正如@Jeff提到的,有几种方法可以做到这一点,但我建议使用loc / iloc来使其更明确(如果尝试歧义,请提早出错):

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

在整数列名称的情况下,后两种选择消除了歧义(正是创建loc / iloc的原因)。例如:

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

2
对不起,打扰您了,但这只是一个非常快速的问题。我看到多余的东西如何[]使结果aDataFrame而不是a Series,但是在pandas docs中何处讨论了这种索引语法?我只是想为这种索引技术获得“官方”名称,以便我真正理解它。谢谢!
sparc_spread

3
@sparc_spread pandas.pydata.org/pandas-docs/stable/indexing.html#basics “您可以将列列表传递给[]以按此顺序选择列。” 我不确定是否有名字!
安迪·海登

是的,看起来好像没有它-但从现在开始,我将继续使用它。令人惊讶的是,API和文档中埋了多少东西。谢谢!
sparc_spread

这种区分对我很有用,因为有时我想要单列DataFrame,以便可以对Series上不可用的数据使用DataFrame方法。(ISTR绘图方法的行为有所不同)。当我意识到我可以使用单元素列表时,这对我来说是一个顿悟!
RufusVS '18 -10-3

4

正如安迪·海登(Andy Hayden)所建议的那样,利用.iloc / .loc索引(单列)数据帧是可行的方法。要注意的另一点是如何表达索引位置。使用列出的索引标签/位置,同时指定要作为数据框索引的参数值;否则将返回“ pandas.core.series.Series”

输入:

    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))

输出:

    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'>

2

您可以使用df.iloc[:, 0:1],在这种情况下,结果向量将是aDataFrame而不是序列。

如你看到的:

在此处输入图片说明


1

提到了这三种方法:

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()是另一种方法。

因为它是一种方法,所以可以在上述第二种方法和第三种方法不适用的情况下使用。特别是,在将某些方法应用于数据框中的列并且要将输出转换为数据框而不是序列时,此方法很有用。例如,在Jupyter Notebook中,一系列不会有漂亮的输出,但是会有一个数据框。

# 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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.