为什么会这样?有办法确保我总是得到一个数据帧吗?
In [1]: import pandas as pd
In [2]: df = pd.DataFrame(data=range(5), index=[1, 2, 3, 3, 3])
In [3]: type(df.loc[3])
Out[3]: pandas.core.frame.DataFrame
In [4]: type(df.loc[1])
Out[4]: pandas.core.series.Series
In [1]: import pandas as pd
In [2]: df = pd.DataFrame(data=range(5), index=[1, 2, 3, 3, 3])
In [3]: type(df.loc[3])
Out[3]: pandas.core.frame.DataFrame
In [4]: type(df.loc[1])
Out[4]: pandas.core.series.Series
虽然行为不一致,但我认为很容易想象出这种情况很方便的案例。无论如何,要每次获取一个DataFrame,只需将列表传递给loc
。还有其他方法,但在我看来,这是最清晰的方法。
In [2]: type(df.loc[[3]])
Out[2]: pandas.core.frame.DataFrame
In [3]: type(df.loc[[1]])
Out[3]: pandas.core.frame.DataFrame
loc
df.loc[:]
= Dataframe
df.loc[int]
= 如果数据框中有多个列,则返回Dataframe;如果只有一个列,则返回Series
df.loc[:, ["col_name"]]
= 如果选择的范围包含多行,则返回Dataframe;如果只有一行,则返回Series
df.loc[:, "col_name"]
= 返回Series
loc
df["col_name"]
= 返回Series
df[["col_name"]]
= 返回Dataframe
df.loc[:, ["col_name"]]
将返回一个系列。 - MrR:
选择所有行,因此结果是正确的。 - Colin Anthonydf.loc[int]
返回一个系列,除非df
的行没有用唯一的整数索引。(不确定这是否是版本相关的行为。) - undefined您有一个有三个索引项3
的索引。因此,df.loc[3]
将返回一个数据帧。
原因是您没有指定列。因此,df.loc[3]
选择所有列的三个项(即列0
),而df.loc[3,0]
将返回一个系列。例如,df.loc[1:2]
也返回一个数据帧,因为您切片了行。
选择单个行(如df.loc[1]
)将返回具有列名称作为索引的系列。
如果您想要始终拥有DataFrame,请像这样切片df.loc[1:1]
。另一个选项是布尔索引(df.loc[df.index==1]
)或take方法(df.take([0])
,但它使用位置而不是标签!)。
df.loc[1:1]
is faster than df.loc[[1]]
- Winanddf['columnName']
来获取一个 Series,使用 df[['columnName']]
来获取一个 Dataframe。不,我不这样认为;请参见编辑
.
DataFrame不能由可能成为Series的元素组成,因为以下代码对于行和列都会给出相同类型的"Series":
import pandas as pd
df = pd.DataFrame(data=[11,12,13], index=[2, 3, 3])
print '-------- df -------------'
print df
print '\n------- df.loc[2] --------'
print df.loc[2]
print 'type(df.loc[1]) : ',type(df.loc[2])
print '\n--------- df[0] ----------'
print df[0]
print 'type(df[0]) : ',type(df[0])
结果
-------- df -------------
0
2 11
3 12
3 13
------- df.loc[2] --------
0 11
Name: 2, dtype: int64
type(df.loc[1]) : <class 'pandas.core.series.Series'>
--------- df[0] ----------
2 11
3 12
3 13
Name: 0, dtype: int64
type(df[0]) : <class 'pandas.core.series.Series'>
.
那么DataFrame是什么?Why is that?
部分以及他在评论中类似的提问single rows to get converted into a series - why not a data frame with one row?
的答案,而Is there a way to ensure I always get back a data frame?
部分已由Dan Allan回答。.
那么什么是DataFrame对象?
DataFrame类生成具有特定结构的实例,源自于NDFrame基类,它本身派生自PandasContainer基类,后者也是Series类的父类。
请注意,这适用于Pandas直到版本0.12。在即将推出的0.13版本中,Series类也将仅从NDFrame类派生。
# with pandas 0.12
from pandas import Series
print 'Series :\n',Series
print 'Series.__bases__ :\n',Series.__bases__
from pandas import DataFrame
print '\nDataFrame :\n',DataFrame
print 'DataFrame.__bases__ :\n',DataFrame.__bases__
print '\n-------------------'
from pandas.core.generic import NDFrame
print '\nNDFrame.__bases__ :\n',NDFrame.__bases__
from pandas.core.generic import PandasContainer
print '\nPandasContainer.__bases__ :\n',PandasContainer.__bases__
from pandas.core.base import PandasObject
print '\nPandasObject.__bases__ :\n',PandasObject.__bases__
from pandas.core.base import StringMixin
print '\nStringMixin.__bases__ :\n',StringMixin.__bases__
结果
Series :
<class 'pandas.core.series.Series'>
Series.__bases__ :
(<class 'pandas.core.generic.PandasContainer'>, <type 'numpy.ndarray'>)
DataFrame :
<class 'pandas.core.frame.DataFrame'>
DataFrame.__bases__ :
(<class 'pandas.core.generic.NDFrame'>,)
-------------------
NDFrame.__bases__ :
(<class 'pandas.core.generic.PandasContainer'>,)
PandasContainer.__bases__ :
(<class 'pandas.core.base.PandasObject'>,)
PandasObject.__bases__ :
(<class 'pandas.core.base.StringMixin'>,)
StringMixin.__bases__ :
(<type 'object'>,)
如果目标是使用索引获取数据集的子集,最好避免使用loc
或iloc
。相反,您应该使用类似于以下语法:
df = pd.DataFrame(data=range(5), index=[1, 2, 3, 3, 3])
result = df[df.index == 3]
isinstance(result, pd.DataFrame) # True
result = df[df.index == 1]
isinstance(result, pd.DataFrame) # True
result = df[df.index == idx]
是一个非常好的选项;完美地适合我的需求。 - ghukill[['column name']]
时,它会返回 Pandas DataFrame 对象,
如果我们使用 ['column name']
,则会得到 Pandas Series 对象。def get_list_from_df_column(df, index, column):
df_or_series = df.loc[index,[column]]
# df.loc[index,column] is also possible and returns a series or a scalar
if isinstance(df_or_series, pd.Series):
resulting_list = df_or_series.tolist() #get list from series
else:
resulting_list = df_or_series[column].tolist()
# use the column key to get a series from the dataframe
return(resulting_list)
.loc[[nonexistent_label]]
时,会出现KeyError
错误。 - Dan Allan.loc
中使用列表会比不使用它慢得多。为了仍然可读但速度更快,最好使用df.loc[1:1]
。 - Jonathan