라벨로 선택하는 Pandas는 때때로 Series를 반환하고 때로는 DataFrame을 반환합니다.
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']
시리즈 df[['columnName']]
를 가져 오고 데이터 프레임 을 가져 오는 데 사용 합니다 .
당신은 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 인스턴스에는 행과 열에서 데이터를 추출하는 방식을 제어하기 위해 만들어진 특정 메서드가 있다는 것을 이해합니다.
The ways these extracting methods work are described in this page: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing
We find in it the method given by Dan Allan and other methods.
Why these extracting methods have been crafted as they were ?
That's certainly because they have been appraised as the ones giving the better possibilities and ease in data analysis.
It's precisely what is expressed in this sentence:
The best way to think about the pandas data structures is as flexible containers for lower dimensional data.
The why of the extraction of data from a DataFRame instance doesn't lies in its structure, it lies in the why of this structure. I guess that the structure and functionning of the Pandas' data structure have been chiseled in order to be as much intellectually intuitive as possible, and that to understand the details, one must read the blog of Wes McKinney.
If the objective is to get a subset of the data set using the index, it is best to avoid using loc
or iloc
. Instead you should use syntax similar to this :
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
If you also select on the index of the dataframe then the result can be either a DataFrame or a Series or it can be a Series or a scalar (single value).
This function ensures that you always get a list from your selection (if the df, index and column are valid):
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)
'Nice programing' 카테고리의 다른 글
Heroku는 Rails 4의 자산 파이프 라인에서 파일을 컴파일하지 않습니다. (0) | 2020.10.13 |
---|---|
Postgres에서 열거 형 값을 삭제하는 방법은 무엇입니까? (0) | 2020.10.13 |
팻 모델 / 씬 컨트롤러 대 서비스 레이어 (0) | 2020.10.12 |
Django에서 모델 객체 대량 생성 (0) | 2020.10.12 |
Android에서 SVG 지원 (0) | 2020.10.12 |