python - 특정 - 파이썬 리스트 데이터프레임 변환




del df.column_name을 사용하여 pandas DataFrame에서 열 삭제 (10)

TL, DR

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

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

전문
열 삭제는 의미 론적으로 다른 열을 선택하는 것과 같습니다. 고려해야 할 몇 가지 추가 방법을 보여 드리겠습니다.

한 번에 여러 개의 열을 삭제하고 존재하지 않는 열을 삭제하려는 일반적인 해결책에 대해서도 집중적으로 설명하겠습니다.

이러한 솔루션을 사용하는 것이 일반적이며 단순한 경우에도 효과적입니다.

설정
pd.DataFrame 를 삭제하려면 dlst df 및 목록을 고려하십시오.

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') 를 실행하는 데 걸리는 시간과 관련이 있습니다. 그 모든 노력을 다한 것처럼 우리는 겸손하게 성과를 향상시킵니다.

사실 가장 좋은 솔루션은 해킹 list(set(df.columns.values.tolist()).difference(dlst)) 에서 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

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

del df['column_name']

그리고 위대한 작품. 왜 다음을 사용할 수 없습니까?

del df.column_name

df.column_name 과 같이 / Series를 액세스 할 수 df.column_name 이 작동 할 것으로 기대됩니다.


팬더 0.21+ 답변

Pandas 버전 0.21은 drop 메소드를 약간 변경하여 renamereindex 메소드의 서명과 일치하는 indexcolumns 매개 변수를 모두 포함합니다.

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

개인적으로, 나는 거의 모든 팬더 방법에서 사용되는 주된 키워드 매개 변수이기 때문에 axis 매개 변수를 사용하여 열 또는 인덱스를 나타내는 것을 선호합니다. 그러나 이제 0.21 버전에서 몇 가지 추가 옵션을 사용할 수 있습니다.


데이터 프레임 ( df )에서 단일 열 ( col_name )을 삭제하려면 다음 중 하나를 수행하십시오.

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

또는

df.drop(col_name, axis=1, inplace=True)

데이터 프레임 ( df )에서 열 목록 ( col_lst = [col_name_1,col_name_2,...] )을 삭제하려면 다음 중 하나를 수행하십시오.

df.drop(col_lst, axis=1, inplace=True)

또는

df.drop(columns=col_lst, inplace=True)

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

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

실제 질문은, 여기에 대부분의 답변을 놓친 위치 :

del df.column_name 사용할 수 del df.column_name ?

처음에 우리는이 문제를 이해할 필요가 있습니다.이 문제는 우리가 파이썬 매직 방법 으로 뛰어 들어야 할 필요가 있습니다 .

Wes가 그의 대답에서 지적했듯이 del df['column'] 는 python 마법 방법 df.__delitem__('column') 매핑됩니다.이 메소드 는 판다에 구현되어 열을 삭제합니다

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

사실 del 은 불리한 환경 때문에 거의 사용되지 않아야합니다. 조심해서 사용하십시오!

del df['column_name'] 을 사용하거나 권장해서는 안되며 del df.column_name 을 고려하지 del df.column_name 한다고 주장 할 수 있습니다.

그러나 이론적으로 del df.column_namemagic method __delattr__ 사용 하여 pandas에서 작동하도록 구현 될 수 있습니다. 그러나 이는 del df['column_name'] 구현이 이미 가지고 있지만보다 적은 정도의 문제로 인해 특정 문제를 야기합니다.

예제 문제

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

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

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

이 문제의 배경이되는 구조적 질문

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

판다가 대답했다 :

  1. 예, 모든면에서 그렇습니다.
  2. 아니요.하지만 원하는 경우 .ix , .loc 또는 .iloc 메소드를 사용할 수 있습니다.
  3. 어쩌면 데이터를 읽으려고 합니까? 그렇다면 속성의 이름이 이미 데이터 프레임에 속한 다른 속성에 의해 사용 되지 않는다면 그렇습니다 . 데이터를 수정 하시겠습니까? 그럼 안돼 .

TLDR;

del df.column_name 수행 할 수 없습니다. pandas는 이러한 종류의 인지 부조화 가 사용자에게 발생하지 않도록 재검토해야 할 필요가있는 아키텍처입니다.

Protip :

df.column_name을 사용하지 마십시오. 꽤 있을지 모르지만 인지 부조화가 발생합니다.

Python의 Zen은 여기에 들어 맞습니다 :

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

그것을 할 수있는 한 가지 방법, 바람직하게는 단지 하나의 방법 만 있어야합니다.

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

특별한 경우는 규칙을 어기는 데 충분하지 않습니다.

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

모호함에 직면하여 추측하려는 유혹을 거부하십시오.


용도:

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

이렇게하면 하나 이상의 열이 제자리에서 삭제됩니다. inplace=True 가 pandas v0.13에 추가되었으며 이전 버전에서는 작동하지 않습니다. 이 경우 결과를 다시 지정해야합니다.

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

파이썬에서 구문상의 한계로 인해 del df.column_name 을 간단하게 작동 del df.column_name 것은 어렵습니다. del df[name] 은 Python 커버 아래에서 df.__delitem__(name) 으로 변환됩니다.


판다 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)

항상 [] 표기법을 사용하는 것이 좋습니다. 그 이유 중 하나는 숫자 표기에 대해 속성 표기법 ( 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 DataFrame에서 열 삭제의 또 다른 방법

In-Place 삭제를 DataFrame(...) 함수를 사용하여 열을 지정하여 새 DataFrame을 만들 수 있습니다.

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

df = pd.DataFrame(my_dict)

다음과 같이 새 DataFrame을 만듭니다.

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

당신은 del / drop으로 얻을 수있는만큼 좋은 결과를 얻습니다.







dataframe