Spalte aus pandas DataFrame löschen


1328

Beim Löschen einer Spalte in einem DataFrame verwende ich:

del df['column_name']

Und das funktioniert super. Warum kann ich Folgendes nicht verwenden?

del df.column_name

Da es möglich ist, auf die Spalte / Serie als zuzugreifen df.column_name, habe ich erwartet, dass dies funktioniert.


2
Beachten Sie, dass diese Frage in Meta diskutiert wird .
RM

Antworten:


858

Wie Sie vermutet haben, ist die richtige Syntax

del df['column_name']

del df.column_nameAufgrund syntaktischer Einschränkungen in Python ist es schwierig, die Arbeit einfach zu machen . del df[name]wird df.__delitem__(name)von Python unter die Decke übersetzt .


25
Mir ist klar, dass dies eine super alte "Antwort" ist, aber meine Neugier ist geweckt - warum ist das eine syntaktische Einschränkung von Python? class A(object): def __init__(self): self.var = 1richtet eine Klasse ein und a = A(); del a.varfunktioniert dann
einwandfrei

13
@dwanderson Der Unterschied besteht darin, dass der DataFrame, wenn eine Spalte entfernt werden soll, eine eigene Behandlung haben muss, damit "wie es geht". Im Fall von wird eine Methode del df[name]übersetzt, df.__delitem__(name)die DataFrame implementieren und an seine Anforderungen anpassen kann. Im Fall von del df.namewird die Mitgliedsvariable entfernt, ohne dass die Möglichkeit besteht, dass benutzerdefinierter Code ausgeführt wird. Betrachten Sie Ihr eigenes Beispiel - können Sie den del a.varAusdruck "Variable löschen" erhalten? Wenn du kannst, sag mir bitte wie. Ich kann nicht :)
Yonatan


5
@ Yonatan Eugenes Kommentar gilt auch für Python 2; Deskriptoren sind seit 2.2 in Python 2 und es ist trivial, Ihre Anforderungen zu erfüllen;)
CS

1
Diese Antwort ist nicht wirklich richtig - die pandasEntwickler haben es nicht getan , aber das bedeutet nicht, dass es schwierig ist, dies zu tun.
wizzwizz4

2185

Der beste Weg, dies bei Pandas zu tun, ist drop:

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

Wo 1ist die Achsnummer ( 0für Zeilen und 1für Spalten).

So löschen Sie die Spalte, ohne sie neu dfzuweisen zu müssen:

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

Schließlich wird durch Spalte fallen Nummer statt durch Spalte Label , versuchen Sie diese zu löschen, die erste zum Beispiel, 2. und 4. Spalten:

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

Arbeiten auch mit "Text" -Syntax für die Spalten:

df.drop(['column_nameA', 'column_nameB'], axis=1, inplace=True)

79
Wird dies delaus irgendeinem Grund empfohlen ?
Bart

20
Obwohl diese Löschmethode ihre Vorzüge hat, beantwortet diese Antwort die gestellte Frage nicht wirklich.
Paul

109
Richtig @Paul, aber aufgrund des Titels der Frage versuchen die meisten Leute, die hier ankommen, herauszufinden, wie eine Spalte gelöscht werden kann.
LondonRob

24
@beardc Ein weiterer Vorteil von dropover delist, dropdass Sie mehrere Spalten gleichzeitig löschen, die Operation an Ort und Stelle ausführen können oder nicht, und auch Datensätze entlang einer beliebigen Achse löschen können (besonders nützlich für eine 3-D-Matrix oder Panel)
Kochfelder

8
Ein weiterer Vorteil von dropover delist, dass drop Teil der Pandas-API ist und Dokumentation enthält.
Modulitos

241

Verwenden:

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

Dadurch werden eine oder mehrere Spalten an Ort und Stelle gelöscht. Beachten Sie, dass dies inplace=Truein pandas v0.13 hinzugefügt wurde und bei älteren Versionen nicht funktioniert. In diesem Fall müssten Sie das Ergebnis zurückweisen:

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

3
Ein Hinweis zu dieser Antwort: Wenn eine 'Liste' verwendet wird, sollten die eckigen Klammern entfernt werden:df.drop(list,inplace=True,axis=1)
edesz

1
Dies sollte wirklich die akzeptierte Antwort sein, da dies die Überlegenheit dieser Methode gegenüber deutlich macht del- kann mehr als eine Spalte gleichzeitig löschen .
dbliss

111

Drop by Index

Erste, zweite und vierte Spalte löschen:

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

Erste Spalte löschen:

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

Es gibt einen optionalen Parameter inplace, mit dem die Originaldaten geändert werden können, ohne eine Kopie zu erstellen.

Knallte

Spaltenauswahl, Hinzufügung, Löschung

Spalte löschen column-name:

df.pop('column-name')

Beispiele:

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

1
Wie kann ich eine Reihe in Pandas knallen lassen?
Kennet Celeste

2
@Yugi Sie können dafür einen transponierten Datenrahmen verwenden. ex - df.T.pop('A')
Uhr Sklave

@ClockSlave Das Original wird dadurch nicht geändert df. Sie könnten tun, df = df.T; df.pop(index); df = df.Taber das scheint übertrieben.
CS95

Wäre df.drop(df.columns[[0]], axis=1, inplace=True)es nicht genug zu verwenden df.drop([0], axis=1)?
Anirban Mukherjee

1
@ Anirban Mukherjee Es kommt darauf an. Wenn Sie den Spaltennamen löschen möchten 0, df.drop(0, axis=1)funktioniert dies gut. Wenn Sie den Spaltennamen nicht kennen und die erste Spalte entfernen müssen df.drop(df.columns[[0]], axis=1, inplace=True), wählen Sie die erste Spalte nach Position aus und legen Sie sie ab.
Jezrael

71

Die eigentliche Frage, die von den meisten Antworten hier übersehen wird, lautet:

Warum kann ich nicht verwenden del df.column_name?

Zuerst müssen wir das Problem verstehen, das es erfordert, dass wir uns mit Python-Magie-Methoden befassen .

Wie Wes in seiner Antwort del df['column']hervorhebt, entspricht dies der Python- Magie-Methode, df.__delitem__('column') die in Pandas implementiert ist, um die Spalte zu löschen

Wie im obigen Link zu Python Magic-Methoden ausgeführt :

In der Tat __del__sollte fast nie wegen der prekären Umstände verwendet werden, unter denen es genannt wird; Verwenden Sie es mit Vorsicht!

Sie könnten argumentieren, dass dies del df['column_name']nicht genutzt oder gefördert werden sollte, und damitdel df.column_name sollte und daher nicht einmal in Betracht gezogen werden sollte.

Theoretisch del df.column_namekönnte man jedoch implementieren, um mit der magischen Methode__delattr__ in Pandas zu arbeiten . Dies bringt jedoch bestimmte Probleme mit sich, Probleme, die diedel df['column_name'] Implementierung bereits hat, jedoch in geringerem Maße.

Beispiel Problem

Was ist, wenn ich eine Spalte in einem Datenrahmen mit dem Namen "dtypes" oder "column" definiere?

Nehmen wir dann an, ich möchte diese Spalten löschen.

del df.dtypeswürde die __delattr__Methode verwirren, als ob sie das Attribut "dtypes" oder die Spalte "dtypes" löschen sollte.

Architekturfragen hinter diesem Problem

  1. Ist ein Datenrahmen eine Sammlung von Spalten ?
  2. Ist ein Datenrahmen eine Sammlung von Zeilen ?
  3. Ist eine Spalte ein Attribut eines Datenrahmens?

Pandas antwortet:

  1. Ja, in jeder Hinsicht
  2. Nein, aber wenn Sie möchten, können Sie das .ix, .locoder verwenden.iloc Methoden.
  3. Vielleicht möchten Sie Daten lesen ? Dann ja , es sei denn, der Name des Attributs wird bereits von einem anderen Attribut übernommen, das zum Datenrahmen gehört. Möchten Sie Daten ändern ? Dann nein .

TLDR;

Sie können dies nicht tun, del df.column_nameda Pandas eine ziemlich wild gewachsene Architektur hat, die überdacht werden muss, damit diese Art von kognitiver Dissonanz bei ihren Benutzern nicht auftritt.

Protip:

Verwenden Sie nicht df.column_name. Es mag hübsch sein, aber es verursacht kognitive Dissonanzen

Zen of Python-Zitate, die hier passen:

Es gibt mehrere Möglichkeiten, eine Spalte zu löschen.

Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun.

Spalten sind manchmal Attribute, manchmal aber auch nicht.

Sonderfälle sind nicht speziell genug, um gegen die Regeln zu verstoßen.

Hat del df.dtypeslöschen Sie die dtypes Attribut oder die dtypes Spalte?

Verweigern Sie angesichts von Zweideutigkeiten die Versuchung zu raten.


"In der Tat __del__sollte fast nie wegen der prekären Umstände verwendet werden, unter denen es genannt wird; verwenden Sie es mit Vorsicht!" ist hier völlig irrelevant, wie die hier verwendete Methode ist __delattr__.
pppery

1
@ppperry Sie zitieren falsch. Es ist das deleingebaute gemeint, nicht die .__del__Instanzmethode. Die deleingebaute kartiert auf __delattr__und __delitem__das ist , was ich meine Argumentation bin Gebäude auf. Vielleicht möchten Sie noch einmal lesen, was ich geschrieben habe.
Firelynx

1
__... __wird von StackExchange
pppery

2
"Verwenden Sie nicht df.column_name. Es mag hübsch sein, aber es verursacht kognitive Dissonanz." Was bedeutet das? Ich bin kein Psychologe, also muss ich nachschlagen, um zu verstehen, was du meinst. Außerdem ist das Zitieren des Zen bedeutungslos, da es Hunderte von gültigen Möglichkeiten gibt, dasselbe bei Pandas zu tun.
CS95

58

Eine nette Ergänzung ist die Möglichkeit, Spalten nur dann zu löschen, wenn sie vorhanden sind . Auf diese Weise können Sie mehr Anwendungsfälle abdecken und nur die vorhandenen Spalten aus den an sie übergebenen Beschriftungen löschen:

Fügen Sie einfach Fehler hinzu = 'ignorieren' , zum Beispiel:

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • Dies ist neu ab Pandas 0.16.1. Die Dokumentation ist hier .

41

ab Version 0.16.1 können Sie tun

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

3
Und dies unterstützt auch das Löschen mehrerer Spalten, von denen einige nicht vorhanden sein müssen (dh ohne Fehler auszulösen errors= 'ignore') df.drop(['column_1','column_2'], axis=1 , inplace=True,errors= 'ignore'), wenn eine solche Anwendung gewünscht wird!
Myon

31

Es ist empfehlenswert, immer die []Notation zu verwenden. Ein Grund dafür ist, dass die Attributnotation ( df.column_name) für nummerierte Indizes nicht funktioniert:

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

26

Pandas 0.21+ Antwort

Pandas Version 0.21 hat die geänderte dropMethode leicht beide enthalten die indexund columnsParameter , die die Unterschrift des anzupassen renameund reindexMethoden.

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

Persönlich bevorzuge ich die Verwendung des axisParameters zur Bezeichnung von Spalten oder Indizes, da dies der vorherrschende Schlüsselwortparameter ist, der in fast allen Pandas-Methoden verwendet wird. Jetzt haben Sie in Version 0.21 einige zusätzliche Optionen.


1
df.drop (['column_a', 'column_c'], axis = 1) | es funktioniert für mich jetzt
YouAreAwesome

21

In Pandas 0.16.1+ können Sie Spalten nur löschen, wenn sie gemäß der von @eiTanLaVi veröffentlichten Lösung vorhanden sind. Vor dieser Version können Sie dasselbe Ergebnis über ein bedingtes Listenverständnis erzielen:

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

14

TL; DR

Viel Aufwand, um eine geringfügig effizientere Lösung zu finden. Es ist schwierig, die zusätzliche Komplexität zu rechtfertigen, während die Einfachheit von geopfert wirddf.drop(dlst, 1, errors='ignore')

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

Präambel
Löschen einer Spalte entspricht semantisch dem Auswählen der anderen Spalten. Ich werde einige zusätzliche Methoden zeigen, die zu berücksichtigen sind.

Ich werde mich auch auf die allgemeine Lösung konzentrieren, mehrere Spalten gleichzeitig zu löschen und den Versuch zu ermöglichen, nicht vorhandene Spalten zu löschen.

Die Verwendung dieser Lösungen ist allgemein und funktioniert auch für den einfachen Fall.


Setup
Betrachten Sie die pd.DataFrame dfzu löschende Listedlst

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

Das Ergebnis sollte folgendermaßen aussehen:

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

Da ich das Löschen einer Spalte mit der Auswahl der anderen Spalten gleichsetze, werde ich sie in zwei Typen unterteilen:

  1. Etikettenauswahl
  2. Boolesche Auswahl

Etikettenauswahl

Wir beginnen mit der Erstellung der Liste / des Arrays von Beschriftungen, die die Spalten darstellen, die wir behalten möchten, und ohne die Spalten, die wir löschen möchten.

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

Spalten aus Beschriftungen
Um den Auswahlprozess zu vergleichen, nehmen Sie an:

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

Dann können wir auswerten

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

Welche alle bewerten zu:

   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

Boolesche Scheibe

Wir können ein Array / eine Liste von Booleschen Werten zum Schneiden erstellen

  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)

Spalten aus Boolean
Zum Vergleich

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

Welche alle bewerten zu:

   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

Robustes Timing

Funktionen

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)

Testen

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

Dies ist relativ zu der Zeit, die zum Ausführen benötigt wird df.drop(dlst, 1, errors='ignore'). Nach all diesen Anstrengungen scheinen wir die Leistung nur geringfügig zu verbessern.

Geben Sie hier die Bildbeschreibung ein

In der Tat verwenden die besten Lösungen reindexoder reindex_axisauf dem Hack list(set(df.columns.values.tolist()).difference(dlst)). Eine knappe Sekunde und immer noch geringfügig besser als sie dropist 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

2

Die Punktsyntax funktioniert in JavaScript, jedoch nicht in Python.

  • Python: del df['column_name']
  • JavaScript: del df['column_name'] oder del df.column_name

2

Wenn Ihr ursprünglicher Datenrahmen dfnicht zu groß ist, Sie keine Speicherbeschränkungen haben und nur wenige Spalten beibehalten müssen, können Sie auch einen neuen Datenrahmen mit nur den Spalten erstellen, die Sie benötigen:

new_df = df[['spam', 'sausage']]

2

Wir können entfernen oder löschen eine bestimmte Spalte oder sprcified Spalten von Tropfen () Methode.

Angenommen, df ist ein Datenrahmen.

Zu entfernende Spalte = column0

Code:

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

So entfernen Sie mehrere Spalten col1, col2 ,. . . , coln, müssen wir alle Spalten, die entfernt werden mussten, in eine Liste einfügen. Entfernen Sie sie dann mit der drop () -Methode.

Code:

df = df.drop([col1, col2, . . . , coln], axis=1)

Ich hoffe es wäre hilfreich.


df = df.drop([col1, col2, . . . , coln], axis=1)Dies funktioniert nicht, wenn ich einen Variablennamen anstelle von Spalte1, Spalte2 usw. anmelde. Ich erhalte eine Fehlerspalte, die nicht in der Achse liegt, wenn sie definitiv vorhanden ist. @Littin Könnten Sie helfen?
RSM

1

Eine andere Möglichkeit, eine Spalte in Pandas DataFrame zu löschen

Wenn Sie nicht nach einer direkten Löschung suchen, können Sie einen neuen DataFrame erstellen, indem Sie die Spalten mit der DataFrame(...)Funktion als angeben

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

df = pd.DataFrame(my_dict)

Erstellen Sie einen neuen DataFrame als

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

Sie erhalten ein Ergebnis, das so gut ist wie das, was Sie mit del / drop erhalten


1
Dies ist technisch korrekt, aber es scheint albern, jede Spalte aufzulisten, die beibehalten werden soll, anstatt nur die eine (oder wenige) Spalten, die Sie löschen möchten.
CS95
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.