问题:Python Pandas:将选定的列保留为DataFrame而不是Series
从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?
回答 0
正如@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
回答 1
正如安迪·海登(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
回答 3
提到了这三种方法:
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()