누군가이 세 가지 슬라이스 방법이 어떻게 다른지 설명 할 수 있습니까?
나는 문서를 보았고 이러한 답변 을 보았지만 여전히 세 가지가 어떻게 다른지 설명 할 수 없다고 생각합니다. 나에게, 그들은 낮은 수준의 슬라이싱에 있기 때문에 대체로 상호 교환 가능한 것처럼 보입니다.
예를 들어의 첫 5 개 행을 가져오고 싶다고 가정 해 보겠습니다 DataFrame
. 이 세 가지가 모두 어떻게 작동합니까?
df.loc[:5]
df.ix[:5]
df.iloc[:5]
누군가 사용의 구별이 더 명확한 세 가지 경우를 제시 할 수 있습니까?
답변
참고 : 팬더 버전 0.20.0 이상으로 ix
되어 사용되지 않는 및 사용 loc
과는 iloc
대신 권장합니다. 필자는 ix
이전 버전의 팬더 사용자를위한 참조로 그대로 설명하는이 답변의 일부를 남겼습니다 . 에 대한 대안을 보여주는 예가 아래에 추가되었습니다 ix
.
먼저 다음 세 가지 방법을 살펴 보겠습니다.
loc
인덱스에서 특정 레이블 이있는 행 (또는 열)을 가져옵니다.iloc
인덱스의 특정 위치 에서 행 (또는 열)을 가져옵니다 (정수만 사용).ix
일반적으로 동작을 시도loc
하지만iloc
색인에 레이블이없는 경우 처럼 동작 합니다.
ix
사용하기 약간 까다로울 수있는 몇 가지 미묘한 점에 주목하는 것이 중요 합니다.
-
색인이 정수 유형 인
ix
경우 레이블 기반 색인 만 사용하고 위치 기반 색인으로 돌아 가지 않습니다. 레이블이 색인에 없으면 오류가 발생합니다. -
인덱스에 정수만 포함되어 있지 않은 경우 정수가 지정된
ix
경우 레이블 기반 인덱싱 대신 위치 기반 인덱싱을 즉시 사용합니다. 그러나ix
다른 유형 (예 : 문자열)이 제공되면 레이블 기반 색인 작성을 사용할 수 있습니다.
세 가지 방법의 차이점을 설명하기 위해 다음 시리즈를 고려하십시오.
>>> s = pd.Series(np.nan, index=[49,48,47,46,45, 1, 2, 3, 4, 5])
>>> s
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN
정수 값으로 슬라이싱을 살펴 보겠습니다 3
.
이 경우 s.iloc[:3]
처음 3 개 행을 반환하고 (3을 위치로 취급하므로) s.loc[:3]
처음 8 개 행을 반환합니다 (3을 레이블로 취급하므로).
>>> s.iloc[:3] # slice the first three rows
49 NaN
48 NaN
47 NaN
>>> s.loc[:3] # slice up to and including label 3
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
2 NaN
3 NaN
>>> s.ix[:3] # the integer is in the index so s.ix[:3] works like loc
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
2 NaN
3 NaN
통지 s.ix[:3]
는 s.loc[:3]
위치에서 작업하기보다는 레이블을 먼저 찾기 때문에 (그리고 인덱스 s
는 정수 유형 임) 동일한 시리즈를 반환합니다 .
인덱스에없는 정수 레이블로 시도하면 어떻게 6
되나요?
여기서 s.iloc[:6]
예상대로 Series의 처음 6 행을 반환합니다. 그러나 인덱스에 없기 s.loc[:6]
때문에 KeyError 6
가 발생합니다.
>>> s.iloc[:6]
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
>>> s.loc[:6]
KeyError: 6
>>> s.ix[:6]
KeyError: 6
위에서 언급 한 미묘함에 따라 s.ix[:6]
이제는 KeyError처럼 작동하려고 loc
하지만 6
인덱스에서 찾을 수 없기 때문에 KeyError가 발생합니다 . 우리의 인덱스는 정수 타입이기 때문에 ix
처럼 동작하지 않습니다 iloc
.
그러나 인덱스가 혼합 유형 인 경우 KeyError를 발생시키는 대신 정수 ix
가 iloc
즉시 작동합니다 .
>>> s2 = pd.Series(np.nan, index=['a','b','c','d','e', 1, 2, 3, 4, 5])
>>> s2.index.is_mixed() # index is mix of different types
True
>>> s2.ix[:6] # now behaves like iloc given integer
a NaN
b NaN
c NaN
d NaN
e NaN
1 NaN
명심 ix
여전히 같은 비 정수와 행동하라를 받아 들일 수 loc
:
>>> s2.ix[:'c'] # behaves like loc given non-integer
a NaN
b NaN
c NaN
일반적으로 레이블을 사용하여 인덱싱하거나 정수 위치를 사용하여 인덱싱하는 경우 예기치 않은 결과를 피 loc
하거나 iloc
피하려면 사용하지 마십시오 ix
.
위치 기반 및 라벨 기반 색인 생성
때로는 DataFrame이 주어지면 행과 열에 대해 레이블 및 위치 인덱싱 방법을 혼합해야합니다.
예를 들어 다음 DataFrame을 고려하십시오. 최선의 방법 행까지 ‘C’에 등을 슬라이스 와 처음 네 개의 열을?
>>> df = pd.DataFrame(np.nan,
index=list('abcde'),
columns=['x','y','z', 8, 9])
>>> df
x y z 8 9
a NaN NaN NaN NaN NaN
b NaN NaN NaN NaN NaN
c NaN NaN NaN NaN NaN
d NaN NaN NaN NaN NaN
e NaN NaN NaN NaN NaN
이전 버전의 팬더 (0.20.0 이전) ix
에서는이 작업을 매우 깔끔하게 수행 할 수 있습니다. 레이블별로 행을 ix
잘라 내고 위치별로 열을 슬라이스 할 수 있습니다 (열의 4
경우 열 이름이 아니기 때문에 기본적으로 위치 기반 슬라이싱을 사용합니다) ) :
>>> df.ix[:'c', :4]
x y z 8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN
이후 버전의 팬더에서는 iloc
다른 방법을 사용 하여이 결과를 얻을 수 있습니다 .
>>> df.iloc[:df.index.get_loc('c') + 1, :4]
x y z 8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN
get_loc()
“이 색인에서 레이블의 위치를 얻습니다”를 의미하는 색인 방법입니다. 와의 슬라이싱 iloc
은 엔드 포인트를 배제 하므로 행 ‘c’를 원할 경우이 값에 1을 추가해야합니다.
팬더의 문서에 더 많은 예제가 있습니다 .
답변
iloc
정수 위치에 따라 작동합니다. 따라서 행 레이블이 무엇이든 관계없이 항상 첫 번째 행을 가져올 수 있습니다.
df.iloc[0]
또는 마지막 다섯 행을 수행하여
df.iloc[-5:]
열에서도 사용할 수 있습니다. 세 번째 열을 검색합니다.
df.iloc[:, 2] # the : in the first position indicates all rows
그것들을 결합하여 행과 열의 교차점을 얻을 수 있습니다.
df.iloc[:3, :3] # The upper-left 3 X 3 entries (assuming df has 3+ rows and columns)
반면에 .loc
명명 된 인덱스를 사용하십시오. 문자열을 행 및 열 레이블로 사용하여 데이터 프레임을 설정합시다.
df = pd.DataFrame(index=['a', 'b', 'c'], columns=['time', 'date', 'name'])
그런 다음 첫 행을 얻을 수 있습니다.
df.loc['a'] # equivalent to df.iloc[0]
'date'
열의 두 번째 두 행
df.loc['b':, 'date'] # equivalent to df.iloc[1:, 1]
등등. 이제, 그것은의 기본 행 및 열 인덱스는 지적 아마 가치가 DataFrame
정수가 0이 경우에 iloc
와 loc
같은 방식으로 작동합니다. 이것이 세 가지 예가 동일한 이유입니다. 문자열 또는 날짜 시간과 같이 숫자가 아닌 인덱스 df.loc[:5]
가 있으면 오류가 발생합니다.
또한 데이터 프레임을 사용하여 열 검색을 수행 할 수 있습니다 __getitem__
.
df['time'] # equivalent to df.loc[:, 'time']
이제 위치와 명명 된 인덱싱, 즉 행의 이름과 열의 위치를 사용하여 인덱싱을 혼합하려고한다고 가정합니다 (명확히 말하면 행 인덱스에 문자열과 정수가있는 데이터 프레임을 만드는 대신 데이터 프레임에서 선택하는 것을 의미합니다) 열 색인). 여기가 .ix
온다 :
df.ix[:2, 'time'] # the first two rows of the 'time' column
부울 벡터를 loc
메소드에 전달할 수 있다고 언급 할 가치가 있다고 생각합니다 . 예를 들면 다음과 같습니다.
b = [True, False, True]
df.loc[b]
의 첫 번째와 세 번째 행을 반환합니다 df
. 이것은 df[b]
선택 과 동일 하지만 부울 벡터를 통해 할당하는 데에도 사용할 수 있습니다.
df.loc[b, 'name'] = 'Mary', 'John'
답변
내 의견으로는, 누락 된 값 만있는 DataFrame을 사용하기 때문에 허용되는 대답이 혼란 스럽습니다. 나는 또한 용어처럼하지 않는 위치에 기반 을 위해 .iloc
대신, 선호하는 위치의 정수 훨씬 더 자세한 설명과 정확히 같은 .iloc
의미합니다. 핵심 단어는 정수입니다- .iloc
정수가 필요합니다.
자세한 내용 은 서브셋 선택에 대한 매우 자세한 블로그 시리즈 를 참조하십시오.
.ix는 더 이상 사용되지 않으며 모호하므로 절대 사용해서는 안됩니다.
때문에 .ix
IS가되지 않는 우리는 차이점에 초점을 맞출 것이다 .loc
및 .iloc
.
차이점에 대해 이야기하기 전에 DataFrame에 각 열과 각 인덱스를 식별하는 데 도움이되는 레이블이 있다는 것을 이해해야합니다. 샘플 DataFrame을 살펴 보겠습니다.
df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
'height':[165, 70, 120, 80, 180, 172, 150],
'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
},
index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])
굵게 표시된 모든 단어 는 레이블입니다. 라벨은, age
, color
, food
, height
, score
및 state
에 사용되는 열 . 다른 레이블, Jane
, Nick
, Aaron
, Penelope
, Dean
, Christina
, Cornelia
에 사용되는 인덱스 .
DataFrame에서 특정 행을 선택하는 기본 방법은 .loc
및 .iloc
인덱서를 사용하는 것입니다. 이 인덱서는 각각 동시에 열을 선택하는 데 사용할 수 있지만 지금은 행에 집중하는 것이 더 쉽습니다. 또한 각 인덱서는 이름 바로 다음에 오는 일련의 대괄호를 사용하여 선택합니다.
.loc은 레이블로만 데이터를 선택합니다.
먼저 .loc
인덱스 또는 열 레이블로 데이터를 선택 하는 인덱서 에 대해 이야기하겠습니다 . 샘플 DataFrame에서 인덱스의 값으로 의미있는 이름을 제공했습니다. 많은 DataFrame에는 의미있는 이름이 없으며 대신 0에서 n-1 사이의 정수로 기본 설정됩니다. 여기서 n은 DataFrame의 길이입니다.
사용할 수있는 세 가지 입력이 있습니다 .loc
- 끈
- 문자열 목록
- 문자열을 시작 및 중지 값으로 사용하는 슬라이스 표기법
문자열이있는 .loc을 사용하여 단일 행 선택
단일 데이터 행을 선택하려면 다음에 괄호 안에 색인 레이블을 배치하십시오 .loc
.
df.loc['Penelope']
이것은 데이터 행을 시리즈로 리턴합니다.
age 4
color white
food Apple
height 80
score 3.3
state AL
Name: Penelope, dtype: object
문자열 목록이있는 .loc을 사용하여 여러 행 선택
df.loc[['Cornelia', 'Jane', 'Dean']]
목록에 지정된 순서대로 행이있는 DataFrame을 반환합니다.
슬라이스 표기법이있는 .loc를 사용하여 여러 행 선택
슬라이스 표기법은 시작, 중지 및 단계 값으로 정의됩니다. 레이블로 슬라이스 할 때 팬더는 리턴 값에 중지 값을 포함합니다. Aaron에서 Dean까지 다음 조각이 포함됩니다. 단계 크기는 명시 적으로 정의되어 있지 않지만 기본값은 1입니다.
df.loc['Aaron':'Dean']
복잡한 슬라이스는 Python 목록과 같은 방식으로 가져올 수 있습니다.
.iloc은 정수 위치로만 데이터를 선택합니다
이제로 넘어 갑시다 .iloc
. DataFrame의 모든 데이터 행과 열에는이를 정의하는 정수 위치가 있습니다. 이것은 출력에 시각적으로 표시되는 레이블에 추가됩니다 . 정수 위치는 단순히 0에서 시작하는 상단 / 왼쪽의 행 / 열 수입니다.
사용할 수있는 세 가지 입력이 있습니다 .iloc
- 정수
- 정수 목록
- 시작 및 중지 값으로 정수를 사용하는 슬라이스 표기법
정수가있는 .iloc을 사용하여 단일 행 선택
df.iloc[4]
5 번째 행 (정수 위치 4)을 Series로 반환합니다.
age 32
color gray
food Cheese
height 180
score 1.8
state AK
Name: Dean, dtype: object
정수 목록이있는 .iloc을 사용하여 여러 행 선택
df.iloc[[2, -2]]
세 번째와 두 번째 행부터 마지막 행까지의 DataFrame을 반환합니다.
슬라이스 표기법이있는 .iloc을 사용하여 여러 행 선택
df.iloc[:5:3]
.loc 및 .iloc을 사용하여 행과 열을 동시에 선택
두 가지의 뛰어난 기능 중 하나 .loc/.iloc
는 행과 열을 동시에 선택할 수 있다는 것입니다. 위의 예에서 모든 열은 각 선택 항목에서 반환되었습니다. 행과 동일한 입력 유형을 가진 열을 선택할 수 있습니다. 행과 열 선택을 쉼표로 구분하면 됩니다.
예를 들어 다음과 같이 열 높이, 점수 및 상태만으로 Jane과 Dean 열을 선택할 수 있습니다.
df.loc[['Jane', 'Dean'], 'height':]
행의 레이블 목록과 열의 슬라이스 표기법을 사용합니다.
.iloc
정수만 사용하여 자연스럽게 유사한 작업을 수행 할 수 있습니다 .
df.iloc[[1,4], 2]
Nick Lamb
Dean Cheese
Name: food, dtype: object
라벨과 정수 위치를 통한 동시 선택
.ix
유용하지만 때로는 혼란스럽고 모호한 레이블 및 정수 위치와 동시에 선택하는 데 사용되었으며 고맙게도 더 이상 사용되지 않습니다. 레이블과 정수 위치를 혼합하여 선택해야하는 경우 선택 레이블 또는 정수 위치를 모두 선택해야합니다.
우리가 행을 선택하려는 경우 예를 들어, Nick
및 Cornelia
열 2, 4와 함께를, 우리가 사용할 수있는 .loc
다음과 라벨에 정수를 변환 :
col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names]
또는 get_loc
index 메소드 를 사용하여 인덱스 레이블을 정수로 변환하십시오 .
labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]
부울 선택
.loc 인덱서는 부울 선택을 수행 할 수도 있습니다. 우리가 모든 행을 찾는 데 관심이 있다면 예를 들어, 연령은 30 위에 반환 단지 wher food
과 score
열이 우리가 다음을 수행 할 수 있습니다 :
df.loc[df['age'] > 30, ['food', 'score']]
이것을 복제 .iloc
할 수 는 있지만 부울 시리즈를 전달할 수는 없습니다. 부울 시리즈를 다음과 같이 numpy 배열로 변환해야합니다.
df.iloc[(df['age'] > 30).values, [2, 4]]
모든 행 선택
.loc/.iloc
열 선택에만 사용할 수 있습니다 . 다음과 같이 콜론을 사용하여 모든 행을 선택할 수 있습니다.
df.loc[:, 'color':'score':2]
인덱싱 연산자 인 []
은 행과 열을 동시에 선택할 수는 없습니다.
대부분의 사람들은 열을 선택하는 DataFrame 인덱싱 연산자의 기본 목적에 익숙합니다. 문자열은 단일 열을 Series로 선택하고 문자열 목록은 여러 열을 DataFrame으로 선택합니다.
df['food']
Jane Steak
Nick Lamb
Aaron Mango
Penelope Apple
Dean Cheese
Christina Melon
Cornelia Beans
Name: food, dtype: object
목록을 사용하여 여러 열을 선택합니다
df[['food', 'score']]
사람들이 익숙하지 않은 것은 슬라이스 표기법을 사용할 때 행 레이블 또는 정수 위치로 선택이 발생한다는 것입니다. 이것은 매우 혼란스럽고 거의 사용하지 않는 것이지만 작동합니다.
df['Penelope':'Christina'] # slice rows by label
df[2:6:2] # slice rows by integer location
명확성의 .loc/.iloc
선택 행에 대해 매우 바람직하다. 인덱싱 연산자만으로는 행과 열을 동시에 선택할 수 없습니다.
df[3:5, 'color']
TypeError: unhashable type: 'slice'