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.
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.
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
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)
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
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
- jest ramką danych a zbiór kolumny ?
- czy ramka danych jest zbiorem wierszy?
- czy kolumna jest atrybutem ramki danych?
Pandy odpowiedzi:
- Yes, in all ways
- Nie, ale jeśli chcesz, możesz użyć
.ix
,.loc
lub.iloc
metody. - 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.
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 .
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')
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
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)
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.
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 prostotydf.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:
- wybór etykiety
- 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ąć.
-
df.columns.difference(dlst)
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
-
np.setdiff1d(df.columns.values, dlst)
array(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype=object)
-
df.columns.drop(dlst, errors='ignore')
Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
-
list(set(df.columns.values.tolist()).difference(dlst))
# does not preserve order ['E', 'D', 'B', 'F', 'G', 'A', 'C']
-
[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ć
df.loc[:, cols]
df[cols]
df.reindex(columns=cols)
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]}~df.columns.isin(dlst)
~np.in1d(df.columns.values, dlst)
[x not in dlst for x in df.columns.values.tolist()]
(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()]
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.
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
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']
lubdel df.column_name
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
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