Usuń kolumnę z ramki danych pandy za pomocą del df.nazwa kolumny

Podczas usuwania kolumny w ramce danych używam:

del df['column_name']
I to działa świetnie. Dlaczego nie mogę użyć następujących elementów?
del df.column_name

ponieważ możesz uzyskać dostęp do kolumny/serii jako df.column_name, oczekuję, że to zadziała.

Author: Peter Mortensen, 2012-11-16

13 answers

Trudno jest sprawić, by del df.column_name działało po prostu jako wynik ograniczeń składniowych w Pythonie. del df[name] zostaje przetłumaczone na df.__delitem__(name) pod okładkami przez Pythona.

 471
Author: Wes McKinney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 04:23:14

Najlepszym sposobem na to w pandach jest użycie drop:

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

Gdzie 1 jest liczbą osi (0 dla wierszy i 1 dla kolumn.)

Aby usunąć kolumnę bez konieczności ponownego przypisywania df możesz zrobić:

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

Na koniec, aby upuścić po kolumnie numer zamiast po kolumnie Etykieta, spróbuj usunąć, np. 1., 2. i 4. kolumny:

df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index 
 1569
Author: LondonRob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-17 21:50:03

Użycie:

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

Spowoduje usunięcie jednej lub więcej kolumn na swoim miejscu. Zauważ, że inplace=True został dodany w pandas v0.13 i nie będzie działał na starszych wersjach. W takim przypadku musisz przypisać wynik z powrotem:

df = df.drop(columns, axis=1)
 187
Author: Krishna Sankar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 19:44:08

Drop by index

Usuń pierwszą, drugą i czwartą kolumnę:

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

Usuń pierwszą kolumnę:

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

Istnieje opcjonalny parametr inplace tak, że oryginalny dane mogą być modyfikowane bez tworzenia kopii.

Popped

Wybór kolumny, dodanie, usunięcie

Usuń kolumnę column-name:

df.pop('column-name')

Przykłady:

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
 83
Author: jezrael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 19:44:53

Prawdziwe pytanie zadane, pominięte przez większość odpowiedzi tutaj jest:

Dlaczego nie mogę użyć del df.column_name?

Na początku musimy zrozumieć problem, który wymaga od nas zanurzenia się w metody magiczne Pythona.

Jak wskazuje Wes w swojej odpowiedzi del df['column'] maps to the python magic method df.__delitem__('column') który jest zaimplementowany w Pandzie, aby zrzucić kolumnę

Jednak, jak zaznaczono w linku powyżej o python magic metody:

W rzeczywistości, del prawie nigdy nie powinien być używany z powodu niepewnych okoliczności, w których jest nazywany; używaj go ostrożnie!

Można by argumentować, że del df['column_name'] nie powinny być wykorzystywane lub zachęcane, a tym samym del df.column_name nie powinny być nawet brane pod uwagę.

Jednak teoretycznie, del df.column_name można zaimplementować do pracy w pandach używając metody magicznej __delattr__. To jednak wprowadza pewne problemy, problemy które implementacja del df['column_name'] już ma, ale w mniejszym stopniu.

Przykładowy Problem

Co jeśli zdefiniuję kolumnę w ramce danych o nazwie " dtypes "lub"columns".

Następnie Załóżmy, że chcę usunąć te kolumny.

del df.dtypes spowoduje, że metoda __delattr__ pomyli się tak, jakby miała usunąć atrybut" dtypes "lub kolumnę" dtypes".

Architektoniczne pytania stojące za tym problemem

  1. jest ramką danych a zbiór kolumny ?
  2. czy ramka danych jest zbiorem wierszy?
  3. czy kolumna jest atrybutem ramki danych?

Pandy odpowiedzi:

  1. Yes, in all ways
  2. Nie, ale jeśli chcesz, możesz użyć .ix, .loc lub .iloc metody.
  3. może, chcesz przeczytać dane? Więc tak, chyba że nazwa atrybutu jest już przyjmowana przez inny atrybut należący do ramka danych. Czy chcesz zmodyfikować dane? Wtedy Nie .

TLDR;

Nie możesz zrobić del df.column_name, ponieważ pandy mają dość szalenie rozwiniętą architekturę, która musi być ponownie rozważona, aby tego rodzaju dysonans poznawczy nie przyszło do głowy użytkownikom.

Protip:

Nie używaj df.nazwa kolumny może być ładna, ale powoduje dysonans poznawczy

Zen cytatów Pythona, który pasuje tutaj:

Tam jest wiele sposobów usuwania kolumny.

Powinien być jeden, a najlepiej tylko jeden, oczywisty sposób.

Kolumny są czasami atrybutami, ale czasami nie.

Specjalne przypadki nie są wystarczająco specjalne, aby złamać zasady.

Czy del df.dtypes usuwa atrybut dtypes lub kolumnę dtypes?

W obliczu dwuznaczności, Odrzuć pokusę zgadywania.

 55
Author: firelynx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-03 10:01:14

Miłym dodatkiem jest możliwość upuszczania kolumn tylko wtedy, gdy istnieją . W ten sposób możesz pokryć więcej przypadków użycia i zrzuci tylko istniejące kolumny z przekazywanych do nich etykiet:

Wystarczy dodać errors= 'ignore' , na przykład.:

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • to nowość od pandas 0.16.1. Dokumentacja jest tutaj .
 43
Author: eiTan LaVi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 19:48:00

Od wersji 0.16.1 można zrobić

df.drop(['column_name'], axis = 1, inplace = True, errors = 'ignore')
 39
Author: sushmit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-21 21:20:09

To dobra praktyka, aby zawsze używać [] notacji. Jednym z powodów jest to, że notacja atrybutów (df.column_name) nie działa dla indeksów numerowanych:

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
 24
Author: Andy Hayden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-23 19:43:02

W pandas 0.16.1+ możesz upuścić kolumny tylko wtedy, gdy istnieją na rozwiązanie opublikowane przez @eiTanLaVi. Przed tą wersją można osiągnąć ten sam wynik poprzez warunkowe zrozumienie listy:

df.drop([col for col in ['col_name_1','col_name_2',...,'col_name_N'] if col in df], 
        axis=1, inplace=True)
 20
Author: Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-22 15:15:42

Pandy 0.21 + odpowiedz

Pandas w wersji 0.21 zmienił drop metoda nieznacznie uwzględnia zarówno parametry index i columns, aby pasowały do sygnatury metod rename i reindex.

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

Osobiście wolę używać parametru axis do oznaczania kolumn lub indeksu, ponieważ jest to dominujący parametr słowa kluczowego używany w prawie wszystkich metodach pandy. Ale teraz masz kilka dodanych opcji w wersji 0.21.

 12
Author: Ted Petrou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 18:48:41

TL;DR

Wiele wysiłku, aby znaleźć nieco bardziej efektywne rozwiązanie. Trudno uzasadnić dodatkową złożoność przy jednoczesnym poświęceniu prostoty df.drop(dlst, 1, errors='ignore')
df.reindex_axis(np.setdiff1d(df.columns.values, dlst), 1)

Preambuła
Usunięcie kolumny jest semantycznie takie samo jak wybranie pozostałych kolumn. Pokażę kilka dodatkowych metod do rozważenia.

Skupię się również na ogólnym rozwiązaniu usuwania wielu kolumn naraz i pozwalającym na próbę usunięcia kolumn, których nie ma.

Użycie tych rozwiązań jest ogólne i będzie działać również w prostym przypadku.


Setup
Rozważ pd.DataFrame df i lista do usunięcia dlst

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']

Wynik powinien wyglądać następująco:

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

Ponieważ przyrównuję usuwanie kolumny do wybierania pozostałych kolumn, podzielę ją na dwa typy:

  1. wybór etykiety
  2. wybór logiczny

Etykieta Wybór

Zaczynamy od wytworzenia listy / tablicy etykiet, które reprezentują kolumny, które chcemy zachować i bez kolumn, które chcemy usunąć.

  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']
    

Kolumny z etykiet
W celu porównania procesu selekcji, zakładać:

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

Wtedy możemy ocenić

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

Które wszystkie oceniają na:

   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

Boolean Slice

Możemy zbudować tablicę / listę booleanów do krojenia]}
  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)

Kolumny z Boolean
Dla porównania

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

Które wszystkie oceniają na:

   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

Solidny Czas

funkcje

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)

Testowanie

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()

To jest w stosunku do czasu potrzebnego do uruchomienia df.drop(dlst, 1, errors='ignore'). Wygląda na to, że po całym tym wysiłku poprawiamy wydajność tylko skromnie.

Tutaj wpisz opis obrazka

Jeśli faktycznie najlepsze rozwiązania użyć reindex lub reindex_axis na hack list(set(df.columns.values.tolist()).difference(dlst)). Blisko sekundy i nadal bardzo nieznacznie lepszy od drop jest 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
 11
Author: piRSquared,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 14:28:55

Składnia kropki działa w JavaScript, ale nie w Pythonie.

  • Python: del df['column_name']
  • JavaScript: del df['column_name'] lub del df.column_name
 2
Author: Doctor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-04 10:14:49

Inny sposób na usunięcie kolumny w ramce danych Pandy

Jeśli nie szukasz usunięcia w miejscu, możesz utworzyć nową ramkę danych, określając kolumny za pomocą funkcji DataFrame(...) jako

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

df = pd.DataFrame(my_dict)

Utwórz nowy DataFrame jako

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

Otrzymujesz wynik równie dobry jak to, co otrzymujesz z del / drop

 0
Author: Daksh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-09 06:59:06