Удалите столбец из фрейма данных pandas с помощью del df.имя столбца

при удалении столбца в таблице данных я использую:

del df['column_name']

и это прекрасно работает. Почему я не могу использовать следующее?

del df.column_name

как вы можете получить доступ к столбцу/Серия А df.column_name, Я ожидаю, что это сработает.

13 ответов


Это трудно сделать del df.column_name работа просто в результате синтаксических ограничений в Python. del df[name] переводится в df.__delitem__(name) под обложками Python.


лучший способ сделать это в панд, чтобы использовать drop:

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

здесь 1 - это ось номер (0 для строк и 1 для столбцов.)

чтобы удалить столбец, не назначив df вы можете сделать:

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

наконец, чтобы перейти по колонке вместо колонки метка, попробуйте удалить, например, 1-й, 2-й и 4-й столбцы:

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 был добавлен в pandas 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?

сначала нам нужно понять проблему, которая требует от нас погружения в волшебные методы python.

как Уэс в своем ответе del df['column'] карты на python магический метод df.__delitem__('column') что это выполнены в панд, чтобы удалить столбец

однако, как указал в ссылке выше о волшебные методы python:

в самом деле дель почти никогда не следует использовать из-за опасных обстоятельств, при которых он называется; используйте его с осторожностью!

вы могли бы поспорить, что del df['column_name'] не следует применять или поощрять, и тем самым del df.column_name даже не следует рассматривать.

однако, в теории, del df.column_name может быть выполнен для работы в панд, используя the магический метод __delattr__. Однако это создает определенные проблемы, проблемы, которые del df['column_name'] реализация уже есть, но в меньшей степени.


приятным дополнением является возможность удалить столбцы, только если они существуют. Таким образом, вы можете охватить больше вариантов использования, и он будет отбрасывать только существующие столбцы из переданных ему меток:

просто добавить ошибки= 'ignore', например.:

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • это новое из pandas 0.16.1 и далее. Документация здесь.

С версии 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 метод слегка включить оба index и columns параметры, соответствующие сигнатуре rename и reindex методы.

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)

преамбула
Удаление столбца семантически совпадает с выбором других столбцов. Я покажу несколько дополнительных методов.

я также сосредоточусь на общем решении удаления нескольких столбцов одновременно и с учетом попытка удалить столбцы отсутствует.

использование этих решений является общим и будет работать и для простого случая.


настройка
Рассмотрим pd.DataFrame df и список удалить 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']

результат должен выглядеть так:

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)

столбцы Boolean
Для сравнения

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 is 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.

  • Python:del df['column_name']
  • JavaScript:del df['column_name'] или del df.column_name

другой способ удаления столбца в Pandas DataFrame

Если вы не ищете удаление на месте, вы можете создать новый фрейм данных, указав столбцы с помощью