Удалить столбец из таблицы данных с помощью панды-дель-ДФ.имя столбца



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



del df['column_name']


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



del df.column_name


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

1713   13  

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 почти никогда не следует использовать из-за опасных обстоятельств, при которых он называется; используйте его с осторожностью!

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

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

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

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

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors='ignore')
  • это новое от Панды 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+ ответ

панды версии 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)

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

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

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


Setup
Рассмотрим pd.DataFramedf и список удалить 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)

столбцы Логическое
Ради сравнения

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 и 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

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

Comments

    Ничего не найдено.