development

Pandas DataFrame에서 열 삭제

big-blog 2020. 9. 27. 13:03
반응형

Pandas DataFrame에서 열 삭제


DataFrame에서 열을 삭제할 때 다음을 사용합니다.

del df['column_name']

그리고 이것은 훌륭하게 작동합니다. 왜 다음을 사용할 수 없습니까?

del df.column_name

열 / 시리즈에으로 액세스 할 수 있으므로 df.column_name이것이 작동 할 것으로 예상합니다.


짐작했듯이 올바른 구문은

del df['column_name']

del df.column_namePython의 구문 적 제한으로 인해 단순히 작업 을 만드는 것은 어렵습니다 . 파이썬에 의해 커버 아래로 del df[name]번역됩니다 df.__delitem__(name).


pandas에서이를 수행하는 가장 좋은 방법은 다음을 사용하는 것입니다 drop.

df = df.drop('column_name', 1)

번호 1어디 입니까 ( 0행 및 1열).

재할 당하지 않고 열을 삭제하려면 df다음을 수행하십시오.

df.drop('column_name', axis=1, inplace=True)

마지막으로 레이블 대신 번호 별로 삭제하려면 다음과 같이 삭제하십시오. 예를 들어 1, 2, 4 번째 열이 있습니다.

df = df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 

사용하다:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)

하나 이상의 열이 제자리에서 삭제됩니다. 참고 inplace=True팬더 추가되었다 V0.13 및 이전 버전에서 작동하지 않습니다. 이 경우 결과를 다시 할당해야합니다.

df = df.drop(columns, axis=1)

인덱스 별 드롭

첫 번째, 두 번째 및 네 번째 열을 삭제합니다.

df.drop(df.columns[[0,1,3]], axis=1, inplace=True)

첫 번째 열 삭제 :

df.drop(df.columns[[0]], axis=1, inplace=True)

inplace복사본을 만들지 않고도 원본 데이터를 수정할 수 있도록 선택적 매개 변수 가 있습니다.

열 선택, 추가, 삭제

열 삭제 column-name:

df.pop('column-name')

예 :

df = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6]), ('C', [7,8, 9])], orient='index', columns=['one', 'two', 'three'])

print df:

   one  two  three
A    1    2      3
B    4    5      6
C    7    8      9

df.drop(df.columns[[0]], axis=1, inplace=True) print df:

   two  three
A    2      3
B    5      6
C    8      9

three = df.pop('three') print df:

   two
A    2
B    5
C    8

여기에서 대부분의 답변에서 놓친 실제 질문은 다음과 같습니다.

왜 사용할 수 del df.column_name없습니까?

처음에는 문제를 이해해야하는데,이 문제를 해결하려면 파이썬 매직 메서드 에 뛰어 들어야합니다 .

Wes가 그의 답변에서 지적했듯이 pandas에서 구현 되는 del df['column']파이썬 마법 방법에 매핑 하여 열을 삭제합니다.df.__delitem__('column')

그러나 위의 링크에서 지적했듯이 파이썬 매직 메서드에 대한 :

실제로 del 은 호출되는 불안정한 상황 때문에 거의 사용해서는 안됩니다. 주의해서 사용하십시오!

당신은 그것을 del df['column_name']사용하거나 장려해서는 안된다고 주장 할 수 있으며, del df.column_name그렇게해서 고려해서는 안됩니다.

그러나 이론적으로 마술 방법을del df.column_name 사용 하여__delattr__ 팬더에서 작동하도록 구현할 수 있습니다 . 그러나 이것은 del df['column_name']구현이 이미 가지고 있지만 그 정도는 덜한 특정 문제를 소개 합니다.

예제 문제

"dtypes"또는 "columns"라는 데이터 프레임에 열을 정의하면 어떻게됩니까?

그런 다음이 열을 삭제한다고 가정합니다.

del df.dtypes__delattr__"dtypes"속성 또는 "dtypes"열을 삭제해야하는 것처럼 메서드를 혼란스럽게 만듭니다 .

이 문제에 대한 구조적 질문

  1. 데이터 프레임은 모음 입니까?
  2. 데이터 프레임이 모음 입니까?
  3. 이 데이터 프레임 속성 입니까?

팬더 답변 :

  1. 예, 모든면에서
  2. 아니요,하지만 원하는 경우 .ix, .loc또는 .iloc메서드를 사용할 수 있습니다 .
  3. 아마도 데이터 읽고습니까? 그리고 , 하지 않는 속성의 이름은 이미 dataframe에 속하는 다른 속성에 의해 취해진 다. 데이터 수정 하시겠습니까? 그럼 안돼 .

TLDR;

del df.column_namepandas는 이러한 종류의 인지 부조화 가 사용자에게 발생하지 않도록 재고해야하는 상당히 크게 성장한 아키텍처를 가지고 있기 때문에 그렇게 할 수 없습니다 .

Protip :

df.column_name을 사용하지 마십시오. 예쁘지 만인지 부조화를 유발합니다.

여기에 맞는 Zen of Python 인용문 :

열을 삭제하는 방법에는 여러 가지가 있습니다.

이를 수행하는 분명한 방법은 하나, 바람직하게는 하나만 있어야합니다.

열은 때때로 속성이지만 때로는 그렇지 않습니다.

특별한 경우는 규칙을 어길만큼 특별하지 않습니다.

del df.dtypesdtypes 속성 또는 dtypes 열을 삭제 합니까 ?

모호함에도 불구하고 추측하려는 유혹을 거부하십시오.


좋은 추가 기능은 열이 존재하는 경우에만 삭제 하는 기능 입니다. 이렇게하면 더 많은 사용 사례를 다룰 수 있으며 전달 된 레이블에서 기존 열만 삭제합니다.

예를 들어 errors = 'ignore'를 추가하기 만하면됩니다 . :

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')

버전 0.16.1에서 할 수 있습니다

df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')

항상 []표기법을 사용하는 것이 좋습니다 . 한 가지 이유는 속성 표기법 ( df.column_name)이 번호가 매겨진 인덱스에 대해 작동하지 않기 때문입니다 .

In [1]: df = DataFrame([[1, 2, 3], [4, 5, 6]])

In [2]: df[1]
Out[2]:
0    2
1    5
Name: 1

In [3]: df.1
  File "<ipython-input-3-e4803c0d1066>", line 1
    df.1
       ^
SyntaxError: invalid syntax

Pandas 0.16.1+에서는 @eiTanLaVi가 게시 한 솔루션에 따라 존재하는 경우에만 열을 삭제할 수 있습니다. 해당 버전 이전에는 조건부 목록 이해를 통해 동일한 결과를 얻을 수 있습니다.

df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df], 
        axis=1, inplace=True)

팬더 0.21+ 답변

Pandas 버전 0.21은 메서드 의 서명과 일치하도록 매개 변수를 drop모두 포함 하도록 메서드를 약간 변경했습니다 .indexcolumnsrenamereindex

df.drop(columns=['column_a', 'column_c'])

개인적 axis으로 거의 모든 pandas 메서드에서 사용되는 주요 키워드 매개 변수이기 때문에 열 또는 인덱스를 나타내는 매개 변수를 사용하는 것을 선호 합니다. 그러나 이제 0.21 버전에서 몇 가지 추가 선택 사항이 있습니다.


TL; DR

조금 더 효율적인 솔루션을 찾기위한 많은 노력. 단순성을 희생하면서 추가 된 복잡성을 정당화하기 어려움df.drop(dlst, 1, errors='ignore')

df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)

Preamble
열을 삭제하는 것은 다른 열을 선택하는 것과 의미 상 동일합니다. 고려해야 할 몇 가지 추가 방법을 보여 드리겠습니다.

또한 한 번에 여러 열을 삭제하고 존재하지 않는 열을 삭제하려는 시도를 허용하는 일반적인 솔루션에 초점을 맞출 것입니다.

이러한 솔루션을 사용하는 것은 일반적이며 간단한 경우에도 작동합니다.


설정 및 삭제할 항목을
고려하십시오.pd.DataFrame dfdlst

df = pd.DataFrame(dict(zip('ABCDEFGHIJ', range(1, 11))), range(3))
dlst = list('HIJKLM')

df

   A  B  C  D  E  F  G  H  I   J
0  1  2  3  4  5  6  7  8  9  10
1  1  2  3  4  5  6  7  8  9  10
2  1  2  3  4  5  6  7  8  9  10

dlst

['H', 'I', 'J', 'K', 'L', 'M']

결과는 다음과 같아야합니다.

df.drop(dlst, 1, errors='ignore')

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

열을 삭제하는 것과 다른 열을 선택하는 것과 동일하므로 두 가지 유형으로 나눌 것입니다.

  1. 라벨 선택
  2. 부울 선택

라벨 선택

삭제하려는 열없이 보관하려는 열을 나타내는 레이블 목록 / 배열을 만드는 것으로 시작합니다.

  1. df.columns.difference(dlst)

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
  2. np.setdiff1d(df.columns.values, dlst)

    array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
    
  3. df.columns.drop(dlst, errors='ignore')

    Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
  4. list(set(df.columns.values.tolist()).difference(dlst))

    # does not preserve order
    ['E', 'D', 'B', 'F', 'G', 'A', 'C']
    
  5. [x for x in df.columns.values.tolist() if x not in dlst]

    ['A', 'B', 'C', 'D', 'E', 'F', 'G']
    

레이블의 열
선택 프로세스를 비교하기 위해 다음을 가정합니다.

 cols = [x for x in df.columns.values.tolist() if x not in dlst]

그런 다음 평가할 수 있습니다.

  1. df.loc[:, cols]
  2. df[cols]
  3. df.reindex(columns=cols)
  4. df.reindex_axis(cols, 1)

모두 평가 :

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

부울 슬라이스

슬라이싱을 위해 배열 / 부울 목록을 생성 할 수 있습니다.

  1. ~df.columns.isin(dlst)
  2. ~np.in1d(df.columns.values, dlst)
  3. [x not in dlst for x in df.columns.values.tolist()]
  4. (df.columns.values[:, None] != dlst).all(1)


비교를 위해 부울의 열

bools = [x not in dlst for x in df.columns.values.tolist()]
  1. df.loc[: bools]

모두 평가 :

   A  B  C  D  E  F  G
0  1  2  3  4  5  6  7
1  1  2  3  4  5  6  7
2  1  2  3  4  5  6  7

강력한 타이밍

기능

setdiff1d = lambda df, dlst: np.setdiff1d(df.columns.values, dlst)
difference = lambda df, dlst: df.columns.difference(dlst)
columndrop = lambda df, dlst: df.columns.drop(dlst, errors='ignore')
setdifflst = lambda df, dlst: list(set(df.columns.values.tolist()).difference(dlst))
comprehension = lambda df, dlst: [x for x in df.columns.values.tolist() if x not in dlst]

loc = lambda df, cols: df.loc[:, cols]
slc = lambda df, cols: df[cols]
ridx = lambda df, cols: df.reindex(columns=cols)
ridxa = lambda df, cols: df.reindex_axis(cols, 1)

isin = lambda df, dlst: ~df.columns.isin(dlst)
in1d = lambda df, dlst: ~np.in1d(df.columns.values, dlst)
comp = lambda df, dlst: [x not in dlst for x in df.columns.values.tolist()]
brod = lambda df, dlst: (df.columns.values[:, None] != dlst).all(1)

테스팅

res1 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc slc ridx ridxa'.split(),
        'setdiff1d difference columndrop setdifflst comprehension'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res2 = pd.DataFrame(
    index=pd.MultiIndex.from_product([
        'loc'.split(),
        'isin in1d comp brod'.split(),
    ], names=['Select', 'Label']),
    columns=[10, 30, 100, 300, 1000],
    dtype=float
)

res = res1.append(res2).sort_index()

dres = pd.Series(index=res.columns, name='drop')

for j in res.columns:
    dlst = list(range(j))
    cols = list(range(j // 2, j + j // 2))
    d = pd.DataFrame(1, range(10), cols)
    dres.at[j] = timeit('d.drop(dlst, 1, errors="ignore")', 'from __main__ import d, dlst', number=100)
    for s, l in res.index:
        stmt = '{}(d, {}(d, dlst))'.format(s, l)
        setp = 'from __main__ import d, dlst, {}, {}'.format(s, l)
        res.at[(s, l), j] = timeit(stmt, setp, number=100)

rs = res / dres

rs

                          10        30        100       300        1000
Select Label                                                           
loc    brod           0.747373  0.861979  0.891144  1.284235   3.872157
       columndrop     1.193983  1.292843  1.396841  1.484429   1.335733
       comp           0.802036  0.732326  1.149397  3.473283  25.565922
       comprehension  1.463503  1.568395  1.866441  4.421639  26.552276
       difference     1.413010  1.460863  1.587594  1.568571   1.569735
       in1d           0.818502  0.844374  0.994093  1.042360   1.076255
       isin           1.008874  0.879706  1.021712  1.001119   0.964327
       setdiff1d      1.352828  1.274061  1.483380  1.459986   1.466575
       setdifflst     1.233332  1.444521  1.714199  1.797241   1.876425
ridx   columndrop     0.903013  0.832814  0.949234  0.976366   0.982888
       comprehension  0.777445  0.827151  1.108028  3.473164  25.528879
       difference     1.086859  1.081396  1.293132  1.173044   1.237613
       setdiff1d      0.946009  0.873169  0.900185  0.908194   1.036124
       setdifflst     0.732964  0.823218  0.819748  0.990315   1.050910
ridxa  columndrop     0.835254  0.774701  0.907105  0.908006   0.932754
       comprehension  0.697749  0.762556  1.215225  3.510226  25.041832
       difference     1.055099  1.010208  1.122005  1.119575   1.383065
       setdiff1d      0.760716  0.725386  0.849949  0.879425   0.946460
       setdifflst     0.710008  0.668108  0.778060  0.871766   0.939537
slc    columndrop     1.268191  1.521264  2.646687  1.919423   1.981091
       comprehension  0.856893  0.870365  1.290730  3.564219  26.208937
       difference     1.470095  1.747211  2.886581  2.254690   2.050536
       setdiff1d      1.098427  1.133476  1.466029  2.045965   3.123452
       setdifflst     0.833700  0.846652  1.013061  1.110352   1.287831

fig, axes = plt.subplots(2, 2, figsize=(8, 6), sharey=True)
for i, (n, g) in enumerate([(n, g.xs(n)) for n, g in rs.groupby('Select')]):
    ax = axes[i // 2, i % 2]
    g.plot.bar(ax=ax, title=n)
    ax.legend_.remove()
fig.tight_layout()

이것은 실행하는 데 걸리는 시간에 상대적 df.drop(dlst, 1, errors='ignore')입니다. 그 모든 노력 끝에 우리는 약간만 성능을 향상시키는 것 같습니다.

enter image description here

사실 최고의 솔루션을 사용 reindex하거나 reindex_axis해킹에 list(set(df.columns.values.tolist()).difference(dlst)). 가까운 두번째 여전히 매우 근소하게 더보다는 drop이다 np.setdiff1d.

rs.idxmin().pipe(
    lambda x: pd.DataFrame(
        dict(idx=x.values, val=rs.lookup(x.values, x.index)),
        x.index
    )
)

                      idx       val
10     (ridx, setdifflst)  0.653431
30    (ridxa, setdifflst)  0.746143
100   (ridxa, setdifflst)  0.816207
300    (ridx, setdifflst)  0.780157
1000  (ridxa, setdifflst)  0.861622

점 구문은 JavaScript에서 작동하지만 Python에서는 작동하지 않습니다.

  • 파이썬 : del df['column_name']
  • JavaScript : del df['column_name'] 또는 del df.column_name

Another way of Deleting a Column in Pandas DataFrame

if you're not looking for In-Place deletion then you can create a new DataFrame by specifying the columns using DataFrame(...) function as

my_dict = { 'name' : ['a','b','c','d'], 'age' : [10,20,25,22], 'designation' : ['CEO', 'VP', 'MD', 'CEO']}

df = pd.DataFrame(my_dict)

Create a new DataFrame as

newdf = pd.DataFrame(df, columns=['name', 'age'])

You get a result as good as what you get with del / drop

참고URL : https://stackoverflow.com/questions/13411544/delete-column-from-pandas-dataframe

반응형