Подтвердить что ты не робот

Храните определенные столбцы в панде DataFrame, удаляя все остальное

Скажи, у меня есть таблица данных

    1  2  3  4  5  6 ..  n
A   x  x  x  x  x  x ..  x
B   x  x  x  x  x  x ..  x
C   x  x  x  x  x  x ..  x

И я хочу уменьшить его, чтобы у меня были только, скажем, столбцы 3 и 5, удалив все остальные и сохранив структуру. Как я мог сделать это с пандами? Я думаю, что понимаю, как удалить один столбец, но я не знаю, как сохранить несколько избранных и удалить все остальные.

4b9b3361

Ответ 1

Если у вас есть список столбцов, вы можете просто выбрать их:

In [11]: df
Out[11]:
   1  2  3  4  5  6
A  x  x  x  x  x  x
B  x  x  x  x  x  x
C  x  x  x  x  x  x

In [12]: col_list = [3, 5]

In [13]: df = df[col_list]

In [14]: df
Out[14]:
   3  5
A  x  x
B  x  x
C  x  x

Ответ 2

Вы можете переназначить новое значение на DataFrame, df:

df = df.loc[:,[3, 5]]

Пока нет других ссылок на оригинал DataFrame, старый DataFrame получит сбор мусора.

Обратите внимание, что при использовании df.loc индекс указывается метками. Таким образом, выше 3 и 5 не являются ординалами, они представляют имена меток столбцов. Если вы хотите указать столбцы по порядковому индексу, используйте df.iloc.

Ответ 3

Как сохранить определенные столбцы в панде DataFrame, удалив все остальное?

Ответ на этот вопрос совпадает с ответом на вопрос "Как удалить определенные столбцы в панде DataFrame?" Вот некоторые дополнительные опции к упомянутым до сих пор, наряду с таймингами.

DataFrame.loc

Одним из простых вариантов является выбор, как указано в других ответах,

# Setup.
df
   1  2  3  4  5  6
A  x  x  x  x  x  x
B  x  x  x  x  x  x
C  x  x  x  x  x  x

cols_to_keep = [3,5]

df[cols_to_keep]

   3  5
A  x  x
B  x  x
C  x  x

Или же,

df.loc[:, cols_to_keep]

   3  5
A  x  x
B  x  x
C  x  x

DataFrame.reindex с axis=1 или 'columns' (0. 21+)

Однако у нас также есть reindex, в последних версиях вы указываете axis=1 для удаления:

df.reindex(cols_to_keep, axis=1)
# df.reindex(cols_to_keep, axis='columns')

# for versions < 0.21, use
# df.reindex(columns=cols_to_keep)

   3  5
A  x  x
B  x  x
C  x  x

В старых версиях вы также можете использовать reindex_axis: df.reindex_axis(cols_to_keep, axis=1).


DataFrame.drop

Другой альтернативой является использование drop для выбора столбцов по pd.Index.difference:

# df.drop(cols_to_drop, axis=1)
df.drop(df.columns.difference(cols_to_keep), axis=1)

   3  5
A  x  x
B  x  x
C  x  x

Спектакль

enter image description here

Методы примерно одинаковы с точки зрения производительности; reindex быстрее для меньшего N, а drop быстрее для большего N. Производительность относительно, поскольку ось Y является логарифмической.

Настройка и код

import pandas as pd
import perfplot

def make_sample(n):
    np.random.seed(0)
    df = pd.DataFrame(np.full((n, n), 'x'))
    cols_to_keep = np.random.choice(df.columns, max(2, n // 4), replace=False)

    return df, cols_to_keep 

perfplot.show(
    setup=lambda n: make_sample(n),
    kernels=[
        lambda inp: inp[0][inp[1]],
        lambda inp: inp[0].loc[:, inp[1]],
        lambda inp: inp[0].reindex(inp[1], axis=1),
        lambda inp: inp[0].drop(inp[0].columns.difference(inp[1]), axis=1)
    ],
    labels=['__getitem__', 'loc', 'reindex', 'drop'],
    n_range=[2**k for k in range(2, 13)],
    xlabel='N',   
    logy=True,
    equality_check=lambda x, y: (x.reindex_like(y) == y).values.all()
)

Ответ 4

Для тех, кто ищет способ сделать это на месте:

from pandas import DataFrame
from typing import Set, Any
def remove_others(df: DataFrame, columns: Set[Any]):
    cols_total: Set[Any] = set(df.columns)
    diff: Set[Any] = cols_total - columns
    df.drop(diff, axis=1, inplace=True)

Это создаст дополнение всех столбцов в кадре данных и столбцов, которые должны быть удалены. Те могут быть безопасно удалены. Дроп работает даже на пустом множестве.

>>> df = DataFrame({"a":[1,2,3],"b":[2,3,4],"c":[3,4,5]})
>>> df
   a  b  c
0  1  2  3
1  2  3  4
2  3  4  5

>>> remove_others(df, {"a","b","c"})
>>> df
   a  b  c
0  1  2  3
1  2  3  4
2  3  4  5

>>> remove_others(df, {"a"})
>>> df
   a
0  1
1  2
2  3

>>> remove_others(df, {"a","not","existent"})
>>> df
   a
0  1
1  2
2  3