Pandas에서 인덱스에 항목이 하나만있는 레이블을 선택하면 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
답변
세 개의 인덱스 항목이있는 인덱스가 있습니다 3
. 이러한 이유로 df.loc[3]
데이터 프레임을 반환합니다.
그 이유는 열을 지정하지 않았기 때문입니다. 따라서 df.loc[3]
모든 열 (column 0
) 의 세 항목을 선택 df.loc[3,0]
하고 Series를 반환합니다. 예를 들어 df.loc[1:2]
행을 분할하기 때문에 데이터 프레임도 반환됩니다.
단일 행 ( df.loc[1]
)을 선택하면 열 이름을 인덱스로 사용하는 Series가 반환됩니다.
항상 DataFrame을 갖고 싶다면 df.loc[1:1]
. 또 다른 옵션은 부울 인덱싱 ( df.loc[df.index==1]
) 또는 take 메소드 ( df.take([0])
,하지만 레이블이 아닌 위치를 사용했습니다!)입니다.
답변
df['columnName']
Series df[['columnName']]
를 가져 오고 Dataframe을 가져 오는 데 사용 합니다 .
답변
TLDR
사용할 때 loc
df.loc[:]
= Dataframe
df.loc[int]
= Dataframe 개 이상의 열과 경우 시리즈 는 dataframe 만 1 열이있는 경우
df.loc[:, ["col_name"]]
= Dataframe
df.loc[:, "col_name"]
= 시리즈
사용하지 않음 loc
df["col_name"]
= 시리즈
df[["col_name"]]
= Dataframe
답변
당신은 joris의 대답에 대한 의견을 썼습니다.
“단일 행을 시리즈로 변환 하기위한 설계 결정을 이해하지 못합니다. 행 이 하나 인 데이터 프레임은 어떻습니까?”
단일 행은 시리즈에서 변환 되지 않습니다 .
그것은 IS 시리즈 :No, I don't think so, in fact; see the edit
Pandas 데이터 구조에 대해 생각하는 가장 좋은 방법은 저 차원 데이터를위한 유연한 컨테이너입니다. 예를 들어 DataFrame은 Series의 컨테이너이고 Panel은 DataFrame 개체의 컨테이너입니다. 사전과 같은 방식으로 이러한 컨테이너에서 개체를 삽입하고 제거 할 수 있기를 원합니다.
http://pandas.pydata.org/pandas-docs/stable/overview.html#why-more-than-1-data-structure
Pandas 객체의 데이터 모델은 이와 같이 선택되었습니다. 그 이유는 확실히 내가 모르는 몇 가지 이점을 보장한다는 사실에 있습니다 (인용의 마지막 문장을 완전히 이해하지 못합니다. 그 이유 일 수도 있습니다)
.
편집 : 동의하지 않습니다
DataFrame는 것이다 요소로 구성 할 수없는 일 다음 코드는 동일한 유형 “시리즈”뿐만 아니라에 대한 열의 같은 행을 제공하기 때문에, 시리즈 :
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이 Series로 구성된 척하는 것은 의미가 없습니다. Series는 열이나 행이되어야하기 때문입니다. 어리석은 질문과 비전.
.
그렇다면 DataFrame은 무엇입니까?
이 답변의 이전 버전에서 나는 Why is that?
OP의 질문 부분에 대한 답변과 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이 답변했습니다.
그런 다음 위에서 인용 한 Pandas의 문서에서 Pandas의 데이터 구조가 저 차원 데이터의 컨테이너 로 가장 잘 보인다고 말했듯이 DataFrame 구조의 특성에서 왜 그런지 이해하는 것처럼 보였습니다 .
그러나 나는이 인용 된 조언이 Pandas의 데이터 구조의 본질에 대한 정확한 설명으로 받아 들여서는 안된다는 것을 깨달았습니다.
이 조언은 DataFrame이 Series의 컨테이너라는 것을 의미하지 않습니다.
Series의 컨테이너 (추론의 한 순간에 고려되는 옵션에 따라 행 또는 열)로서의 DataFrame의 정신적 표현이 실제로는 엄격하지 않더라도 DataFrames를 고려하는 좋은 방법임을 표현합니다. “Good”은이 비전이 DataFrame을 효율적으로 사용할 수 있음을 의미합니다. 그게 다야.
.
그렇다면 DataFrame 객체는 무엇입니까?
DataFrame의 클래스는 특정 구조는 유래가 인스턴스 생성 NDFrame의 베이스 클래스, 자체로부터 도출 PandasContainer의 도의 상위 클래스 인 기본 클래스 시리즈 클래스.
이것은 버전 0.12까지 Pandas에 대해 정확합니다. 다가오는 버전 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'>,)
따라서 이제 DataFrame 인스턴스에는 행과 열에서 데이터를 추출하는 방식을 제어하기 위해 만들어진 특정 메서드가 있다는 것을 이해합니다.
이러한 추출 방법이 작동하는 방식은이 페이지에 설명되어 있습니다.
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing
Dan Allan 및 기타 방법이 제공 한 방법을 찾을 수 있습니다.
이러한 추출 방법이 원래대로 만들어진 이유는 무엇입니까?
데이터 분석에서 더 나은 가능성과 용이성을 제공하는 것으로 평가 되었기 때문입니다.
이 문장에서 정확히 표현되는 것은 다음과 같습니다.
Pandas 데이터 구조에 대해 생각하는 가장 좋은 방법은 저 차원 데이터를위한 유연한 컨테이너입니다.
DataFRame 인스턴스에서 데이터를 추출 하는 이유 는 구조에있는 것이 아니라이 구조의 이유 에 있습니다. Pandas의 데이터 구조의 구조와 기능은 최대한 지적으로 직관적이되도록 깎아 내렸고 세부 사항을 이해하려면 Wes McKinney의 블로그를 읽어야합니다.
답변
색인을 사용하여 데이터 세트의 하위 집합을 가져 오는 것이 목표 인 경우 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
답변
데이터 프레임의 인덱스에서도 선택하면 결과는 DataFrame 또는 Series 이거나 Series 또는 스칼라 (단일 값) 일 수 있습니다.
이 함수를 사용하면 선택 항목에서 항상 목록을 가져올 수 있습니다 (df, 인덱스 및 열이 유효한 경우).
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)