팬더 데이터 프레임에서 여러 열 선택


1110

다른 열에 데이터가 있지만 다른 변수에 저장하기 위해 추출하는 방법을 모르겠습니다.

index  a   b   c
1      2   3   4
2      3   4   5

어떻게 선택합니까 'a', 'b'그리고 DF1에 저장?

나는 시도했다

df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']

아무것도 작동하지 않는 것 같습니다.


2
.ix모호 하기 때문에 사용하고 싶지 않습니다 . .iloc또는 .loc필요한 경우 사용하십시오 .
Acumenus

1
헤더 이름을 참조하지 않고 수행 할 수있는 방법이 있습니까? R과 같이 다음 > csvtable_imp_1 <- csvtable_imp[0:6]과 같이 할 수 있습니다 . 첫 번째 열의 델타 양을 0과 6 사이에서 선택합니다. 내가해야 할 일은 판독기 lib로 구분 된 csv-table을 읽는 것입니다.
MichaelR

나는 그것으로 조금 더 일했습니다. 원하는대로 작동하는 것을 찾았습니다. 기본값은 열이 아닌 문자 수를 선택하는 것입니다. infile_1 = largefile_stay.ix[:,0:6]
MichaelR

3
이 늦게 걸려 넘어진 사람들에게는 ix더 이상 사용되지 않습니다. 팬더는 loc(레이블 기반 색인) 또는 iloc(위치 기반 색인)을 사용하는 것이 좋습니다 .
ZaydH

답변:


1768

시도한 방식으로 열 이름 (문자열)을 슬라이스 할 수 없습니다.

여기 몇 가지 옵션이 있습니다. 컨텍스트에서 어떤 변수를 분리 하려는지 알고 있다면 __getitem__구문 ([])에 목록을 전달하여 해당 열에 대한보기 만 반환하면됩니다 .

df1 = df[['a','b']]

또는 이름이 아닌 숫자로 색인을 생성 해야하는 경우 (코드가 처음 두 열의 이름을 몰라도 자동으로 수행해야 함) 대신 다음을 수행 할 수 있습니다.

df1 = df.iloc[:,0:2] # Remember that Python does not slice inclusive of the ending index.

또한 Pandas 객체에 대한 관점과 해당 객체의 사본에 대한 아이디어를 숙지해야합니다. 위의 첫 번째 방법은 원하는 하위 오브젝트 (원하는 슬라이스)의 메모리에 새 사본을 리턴합니다.

그러나 팬더에는 인덱싱 규칙이있어이를 수행하지 않고 대신 원래 오브젝트의 하위 오브젝트 또는 슬라이스와 동일한 메모리 청크를 참조하는 새 변수를 제공합니다. 이는 두 번째 색인 작성 방법으로 발생하므로 copy()정기적 인 사본을 얻기 위해 함수를 사용하여 수정할 수 있습니다 . 이 경우 슬라이스 개체라고 생각되는 것을 변경하면 원래 개체가 변경 될 수 있습니다. 항상 조심해야합니다.

df1 = df.iloc[0,0:2].copy() # To avoid the case where changing df1 also changes df

을 사용하려면 iloc열 위치 (또는 인덱스)를 알아야합니다. 하드 코딩 인덱스 대신 열 위치가 변경 될 수 있으므로 데이터 프레임 객체 의 메서드 기능 iloc과 함께 사용 하여 열 인덱스를 얻을 수 있습니다.get_loccolumns

{df.columns.get_loc(c):c for idx, c in enumerate(df.columns)}

이제이 사전을 사용하여 이름을 사용하고을 사용하여 열에 액세스 할 수 있습니다 iloc.


192
참고 : df[['a','b']]사본을 생성합니다
Wes McKinney

1
예, 이것은 내 대답에 암시 적이었습니다. 사본에 대한 내용은 어떤 이유로 든 사용 을 선호하는ix[] 경우 에만 사용 되었습니다. ix[]
ely

1
ix열이 아닌 행을 색인화합니다. OP가 열을 원한다고 생각했습니다.
호브

9
ix슬라이스 인수를 허용하므로 열을 가져올 수도 있습니다. 예를 들어 df.ix[0:2, 0:2]NumPy 행렬에서와 같이 왼쪽 상단 2x2 하위 배열을 가져옵니다 (물론 열 이름에 따라 다름). 열의 문자열 이름에 슬라이스 구문을 사용할 수도 있습니다 (예 :) df.ix[0, 'Col1':'Col5']. 배열 사이 Col1및 배열 Col5에서 정렬되는 모든 열을 가져 df.columns옵니다. ix행 을 색인화 한다고 말하는 것은 올바르지 않습니다 . 그것은 가장 기본적인 용도입니다. 또한 그보다 훨씬 많은 인덱싱을 지원합니다. 따라서이 ix질문에 대한 일반적인 내용입니다.
ely

7
@AndrewCassidy .ix를 다시 사용하지 마십시오. 정수로 슬라이스하려면 .ilocPython 목록과 마찬가지로 마지막 위치를 배타적으로 사용하십시오.
Ted Petrou

133

버전 0.11.0부터는 인덱서를 사용하여 시도한 방식으로 열 슬라이스 할 수 있습니다.loc .

df.loc[:, 'C':'E']

~에 해당

df[['C', 'D', 'E']]  # or df.loc[:, ['C', 'D', 'E']]

C통해 열 을 반환합니다 E.


임의로 생성 된 DataFrame에 대한 데모 :

import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(100, 6)), 
                  columns=list('ABCDEF'), 
                  index=['R{}'.format(i) for i in range(100)])
df.head()

Out: 
     A   B   C   D   E   F
R0  99  78  61  16  73   8
R1  62  27  30  80   7  76
R2  15  53  80  27  44  77
R3  75  65  47  30  84  86
R4  18   9  41  62   1  82

C에서 E로 열을 가져 오려면 정수 슬라이싱과 달리 열에 'E'가 포함되어 있습니다.

df.loc[:, 'C':'E']

Out: 
      C   D   E
R0   61  16  73
R1   30  80   7
R2   80  27  44
R3   47  30  84
R4   41  62   1
R5    5  58   0
...

레이블을 기반으로 행을 선택하는 것과 동일합니다. 해당 열에서 'R6'에서 'R10'행을 가져옵니다.

df.loc['R6':'R10', 'C':'E']

Out: 
      C   D   E
R6   51  27  31
R7   83  19  18
R8   11  67  65
R9   78  27  29
R10   7  16  94

.loc또한 부울 배열을 허용하므로 배열의 해당 항목이 인 열을 선택할 수 있습니다 True. 예를 들어 열 이름이 목록에 있으면 True를 df.columns.isin(list('BCD'))반환 array([False, True, True, True, False, False], dtype=bool)합니다 ['B', 'C', 'D']. 그렇지 않으면 거짓입니다.

df.loc[:, df.columns.isin(list('BCD'))]

Out: 
      B   C   D
R0   78  61  16
R1   27  30  80
R2   53  80  27
R3   65  47  30
R4    9  41  62
R5   78   5  58
...

110

열 이름 ( df.columns)이 이라고 가정하면 ['index','a','b','c']원하는 데이터는 세 번째 및 네 번째 열에 있습니다. 스크립트가 실행될 때 이름을 모르는 경우이 작업을 수행 할 수 있습니다

newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The "3rd" entry is at slot 2.

EMS가에서 지적한대로 그의 대답 , df.ix더 간결하게 열을 약간 슬라이스,하지만 .columns그것은 바닐라 1-D 파이썬 목록 색인 / 슬라이스 구문을 사용하기 때문에 슬라이스 인터페이스는 더 자연스러운 수 있습니다.

경고 : 열의 'index'이름이 잘못되었습니다 DataFrame. 동일한 레이블이 실제 df.index속성 인 Index배열 에도 사용 됩니다. 따라서 열이 반환되고 df['index']실제 DataFrame 색인이에 의해 반환됩니다 df.index. 은 Index특별한 종류의 Series그것의 요소의 값을 검색에 최적화 된. df.index의 경우 레이블로 행을 조회합니다. 해당 df.columns속성은 pd.Index레이블로 열을 조회하기위한 배열 이기도합니다 .


3
위의 의견에서 언급했듯이 행에만 해당되는 .ix것은 아닙니다 . 범용 슬라이싱 용이며 다차원 슬라이싱에 사용할 수 있습니다. 기본적으로 NumPy의 일반적인 __getitem__구문에 대한 인터페이스 입니다. 즉, 조옮김 연산을 적용하여 열 분할 문제를 행 분할 문제로 쉽게 변환 할 수 있습니다 df.T. 귀하의 예는 columns[1:3]약간 오도하는를 사용합니다. 의 결과 columns는 다음과 같습니다 Series. 배열처럼 취급하지 않도록주의하십시오. 또한 columns[2:3]"3rd & 4th"의견과 일치하도록 변경해야합니다 .
ely

@ Mr.F : 내 [2:4]맞습니다. 당신의 [2:3]잘못입니다. 그리고 표준 파이썬 슬라이싱 표기법을 사용하여 시퀀스 / 시리즈를 생성하는 것은 IMO를 오도하지 않습니다. 그러나 DataFrame 인터페이스를 우회하여 기본 numpy 배열에 액세스하는 것이 좋습니다 ix.
호브

이 경우에는 정확하지만 일반적으로 Pandas의 레이블로 슬라이스하는 것은 슬라이스 끝점을 포함한다는 것 입니다. 따라서 레이블df.columns 로 검색 하고 슬라이스하려는 경우 정수 인덱스 위치로 슬라이스하는 것과는 다른 슬라이스 의미가 있습니다 . 그래도 이전 의견에서는 잘 설명하지 못했습니다.
ely

아, 이제 당신의 요점이 보입니다. 나는 그것이 columns불변의 시리즈 임을 잊었고 getter는 레이블을 인덱스로 사용하도록 재정의되었습니다. 시간을내어 설명해 주셔서 감사합니다.
호브

2
더 이상 사용되지 않음 경고 : .ix는 더 이상 사용되지 않습니다. 따라서 이것은 의미가 있습니다 : newdf = df [df.columns [2 : 4]]
Martien Lubberink

64
In [39]: df
Out[39]: 
   index  a  b  c
0      1  2  3  4
1      2  3  4  5

In [40]: df1 = df[['b', 'c']]

In [41]: df1
Out[41]: 
   b  c
0  3  4
1  4  5

1
내가 같은 예를 들어 뭔가를 열 이름을 변경하고 싶다면 : df[['b as foo', 'c as bar']출력 열 이름을 변경하도록 b같은 foo과 열을 cbar?
kuanb

5
df[['b', 'c']].rename(columns = {'b' : 'foo', 'c' : 'bar'})
Greg Greg

61

나는이 질문이 상당히 오래되었다는 것을 알고 있지만 최신 버전의 팬더에는 정확하게 이것을 할 수있는 쉬운 방법이 있습니다. 열 이름 (문자열) 원하는 방식으로 슬라이스 할 수 있습니다.

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)

6
이것은 생성시에만 가능합니다. 문제는 이미 데이터 프레임에 질문이 있는지 묻는 것입니다.
Banjocat

2
@ Banjocat, 기존 데이터 프레임과 함께 작동
mhery

23

제거 할 열 목록을 제공 drop()하고 Pandas DataFrame 의 함수를 사용하여 필요한 열만 사용하여 DataFrame을 다시 반환 할 수 있습니다 .

그냥 말

colsToDrop = ['a']
df.drop(colsToDrop, axis=1)

다만 열이있는 DataFrame을 반환 b하고 c.

drop방법은 여기 에 문서화되어 있습니다 .


23

팬더와 함께

재치 열 이름

dataframe[['column1','column2']]

iloc 및 색인 번호가있는 특정 열로 선택하려면 다음을 수행하십시오.

dataframe.iloc[:,[1,2]]

로크 열 이름과 같이 사용할 수 있습니다

dataframe.loc[:,['column1','column2']]

20

이 방법이 매우 유용하다는 것을 알았습니다.

# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]

자세한 내용은 여기를 참조 하십시오


예를 들어 2 열과 5 열만 어떻게 생각하십니까?
324

1
그럴 것 surveys_df.iloc [:, [2,5]]입니다.
Julian Gorfer

15

0.21.0부터는 하나 이상의 레이블이 누락 된 목록을 사용 .loc하거나 []사용하는 것이 더 이상 사용되지 않습니다 .reindex. 따라서 귀하의 질문에 대한 답변은 다음과 같습니다.

df1 = df.reindex(columns=['b','c'])

이전 버전에서는 .loc[list-of-labels]적어도 하나의 키를 찾은 한 사용 하면 작동합니다 (그렇지 않으면을 발생 KeyError시킵니다). 이 동작은 더 이상 사용되지 않으며 이제 경고 메시지를 표시합니다. 권장되는 대안은을 사용하는 것 .reindex()입니다.

데이터 인덱싱 및 선택 에서 자세히 알아보기


10

팬더를 사용할 수 있습니다. DataFrame을 만듭니다.

    import pandas as pd
    df = pd.DataFrame([[1, 2,5], [5,4, 5], [7,7, 8], [7,6,9]], 
                      index=['Jane', 'Peter','Alex','Ann'],
                      columns=['Test_1', 'Test_2', 'Test_3'])

DataFrame :

           Test_1  Test_2  Test_3
    Jane        1       2       5
    Peter       5       4       5
    Alex        7       7       8
    Ann         7       6       9

이름별로 하나 이상의 열을 선택하려면

    df[['Test_1','Test_3']]

           Test_1  Test_3
    Jane        1       5
    Peter       5       5
    Alex        7       8
    Ann         7       9

다음을 사용할 수도 있습니다.

    df.Test_2

그리고 열을 얻을 Test_2

    Jane     2
    Peter    4
    Alex     7
    Ann      6

을 사용하여이 행에서 열과 행을 선택할 수도 있습니다 .loc(). 이것을 "슬라이스"라고 합니다. 열 Test_1에서Test_3

    df.loc[:,'Test_1':'Test_3']

"슬라이스"는 다음과 같습니다.

            Test_1  Test_2  Test_3
     Jane        1       2       5
     Peter       5       4       5
     Alex        7       7       8
     Ann         7       6       9

그리고 당신은 원하는 경우 PeterAnn열에서 Test_1Test_3:

    df.loc[['Peter', 'Ann'],['Test_1','Test_3']]

당신은 얻는다 :

           Test_1  Test_3
    Peter       5       5
    Ann         7       9

8

행 인덱스와 열 이름으로 하나의 요소를 얻으려면 다음과 같이 할 수 있습니다 df['b'][0]. 이미지를 만들 수있는 한 간단합니다.

또는 df.ix[0,'b']인덱스와 레이블의 혼합 사용을 사용할 수 있습니다 .

참고 : v0.20 ixloc/ 를 위해 더 이상 사용되지 않습니다 iloc.


6

하나의 다른 쉬운 방법 : 행 반복

iterows를 사용하여

 df1= pd.DataFrame() #creating an empty dataframe
 for index,i in df.iterrows():
    df1.loc[index,'A']=df.loc[index,'A']
    df1.loc[index,'B']=df.loc[index,'B']
    df1.head()

5
iterrows () 사용을 권장하지 마십시오. 팬더의 역사에서 최악의 안티 패턴을 가능하게합니다.
cs95

"최악의 안티 패턴"이 무슨 뜻인지 설명해 주시겠습니까?
Ankita 2016 년

1
IMHO, 팬더를 사용할 때 iterrows ()가 마지막 옵션이어야합니다.
Elf

5

위의 응답에서 논의 된 다른 접근 방식은 사용자가 열 인덱스를 삭제하거나 하위 집합으로 알고 있거나 열 범위를 사용하여 데이터 프레임의 하위 집합을 원한다는 가정을 기반으로합니다 (예 : 'C': 'E') . pandas.DataFrame.drop () 은 확실히 사용자가 정의 한 열 목록을 기반으로 데이터를 하위 집합으로 만드는 옵션입니다 (데이터 프레임의 사본을 항상 사용하고 인플레 이스 매개 변수를 True 로 설정해서는 안됩니다 ).

다른 옵션은 pandas.columns.difference () 를 사용 하는 것입니다.이 이름은 열 이름을 다르게 설정하고 원하는 열을 포함하는 인덱스 유형의 배열을 반환합니다. 다음은 해결책입니다.

df = pd.DataFrame([[2,3,4],[3,4,5]],columns=['a','b','c'],index=[1,2])
columns_for_differencing = ['a']
df1 = df.copy()[df.columns.difference(columns_for_differencing)]
print(df1)

결과는 다음과 같습니다. b c 1 3 4 2 4 5


1
copy ()는 필요하지 않습니다. 즉 : df1 = df[df.columns.difference(columns_for_differencing)]새로운 / 복사 된 데이터 프레임을 반환합니다. 변경 df1하지 않고 수정할 수 있습니다 df. 고마워, btw. 이것이 바로 내가 필요한 것입니다.
Bazyli Debowski

4

df.pop ()을 사용할 수도 있습니다

>>> df = pd.DataFrame([('falcon', 'bird',    389.0),
...                    ('parrot', 'bird',     24.0),
...                    ('lion',   'mammal',   80.5),
...                    ('monkey', 'mammal', np.nan)],
...                   columns=('name', 'class', 'max_speed'))
>>> df
     name   class  max_speed
0  falcon    bird      389.0
1  parrot    bird       24.0
2    lion  mammal       80.5
3  monkey  mammal 

>>> df.pop('class')
0      bird
1      bird
2    mammal
3    mammal
Name: class, dtype: object

>>> df
     name  max_speed
0  falcon      389.0
1  parrot       24.0
2    lion       80.5
3  monkey        NaN

이것이 도움이되는지 알려주십시오. df.pop (c)


3

나는 그것에 대한 몇 가지 대답을 보았지만 나에게 불분명했습니다. 관심있는 항목을 어떻게 선택 하시겠습니까? 이에 대한 대답은 목록에 수집 된 경우 목록을 사용하여 열을 참조 할 수 있다는 것입니다.

print(extracted_features.shape)
print(extracted_features)

(63,)
['f000004' 'f000005' 'f000006' 'f000014' 'f000039' 'f000040' 'f000043'
 'f000047' 'f000048' 'f000049' 'f000050' 'f000051' 'f000052' 'f000053'
 'f000054' 'f000055' 'f000056' 'f000057' 'f000058' 'f000059' 'f000060'
 'f000061' 'f000062' 'f000063' 'f000064' 'f000065' 'f000066' 'f000067'
 'f000068' 'f000069' 'f000070' 'f000071' 'f000072' 'f000073' 'f000074'
 'f000075' 'f000076' 'f000077' 'f000078' 'f000079' 'f000080' 'f000081'
 'f000082' 'f000083' 'f000084' 'f000085' 'f000086' 'f000087' 'f000088'
 'f000089' 'f000090' 'f000091' 'f000092' 'f000093' 'f000094' 'f000095'
 'f000096' 'f000097' 'f000098' 'f000099' 'f000100' 'f000101' 'f000103']

extracted_features63 개의 열을 지정 하는 다음 list / numpy 배열이 있습니다. 원래 데이터 세트에는 103 개의 열이 있으며 정확하게 추출하고 싶습니다.

dataset[extracted_features]

그리고 당신은 이것으로 끝날 것입니다

여기에 이미지 설명을 입력하십시오

머신 러닝 (특히 기능 선택)에서 자주 사용하는 기능입니다. 다른 방법도 논의하고 싶지만 이미 다른 스택 오버 플라워로 덮여 있다고 생각합니다. 도움이 되었기를 바랍니다.


2

pandas.DataFrame.filter방법을 사용 하여 다음과 같이 열을 필터링하거나 순서를 바꿀 수 있습니다 .

df1 = df.filter(['a', 'b'])

0
df[['a','b']] # select all rows of 'a' and 'b'column 
df.loc[0:10, ['a','b']] # index 0 to 10 select column 'a' and 'b'
df.loc[0:10, ['a':'b']] # index 0 to 10 select column 'a' to 'b'
df.iloc[0:10, 3:5] # index 0 to 10 and column 3 to 5
df.iloc[3, 3:5] # index 3 of column 3 to 5
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.