Выбор/исключение наборов столбцов в пандах

Я хотел бы создать представления или кадры данных из существующего кадра данных на основе выбора столбцов.

Например, я хотел бы создать df2 из df1 который содержит все столбцы из него, кроме двух из них. Я пытался сделать следующее, но это не сработало:

import numpy as np
import pandas as pd

# Create a dataframe with columns A,B,C and D
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

# Try to create a second dataframe df2 from df with all columns except 'B' and D
my_cols = set(df.columns)
my_cols.remove('B').remove('D')

# This returns an error ("unhashable type: set")
df2 = df[my_cols]

Что я делаю неправильно? Возможно, в более общем плане, какие механизмы у панды для поддержки выбора и исключения произвольных наборов столбцов из кадра данных?

Ответ 1

Вы можете удалить столбцы, которые вам не нужны, или выбрать те, которые вам нужны

# Using DataFrame.drop
df.drop(df.columns[[1, 2]], axis=1, inplace=True)

# drop by Name
df1 = df1.drop(['B', 'C'], axis=1)

# Select the ones you want
df1 = df[['a','d']]

Ответ 2

Существует новый метод индекса, называемый difference. Он возвращает исходные столбцы, при этом столбцы передаются как аргумент.

df2 = df[df.columns.difference(['B', 'D'])]

Здесь вывод используется для фильтрации столбцов B и D из df.

Ответ 3

Вам не нужно преобразовывать это в набор:

cols = [col for col in df.columns if col not in ['B', 'D']]
df2 = df[cols]

Ответ 4

Также ознакомьтесь со встроенной функцией DataFrame.filter.

Минималистский, но жадный подход (достаточный для данного df):

df.filter(regex="[^BD]")

Консервативный/ленивый подход (только для точных совпадений):

df.filter(regex="^(?!(B|D)$).*$")

Консервативный и общий:

exclude_cols = ['B','C']
df.filter(regex="^(?!({0})$).*$".format('|'.join(exclude_cols)))

Ответ 5

Другой вариант, без удаления или фильтрации в цикле:

import numpy as np
import pandas as pd

# Create a dataframe with columns A,B,C and D
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

# include the columns you want
df[df.columns[df.columns.isin(['A', 'B'])]]

# or more simply include columns:
df[['A', 'B']]

# exclude columns you don't want
df[df.columns[~df.columns.isin(['C','D'])]]

Ответ 6

Вам просто нужно преобразовать set в list

import pandas as pd
df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
my_cols = set(df.columns)
my_cols.remove('B')
my_cols.remove('D')
my_cols = list(my_cols)
df2 = df[my_cols]

Ответ 7

Здесь, как создать копию DataFrame, исключая список столбцов:

df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))
df2 = df.drop(['B', 'D'], axis=1)

Но будьте осторожны! Вы указываете мнения в своем вопросе, предлагая, что если вы изменили df, вы бы хотели, чтобы df2 тоже изменился. (Подобно представлению в базе данных.)

Этот метод не достигает этого:

>>> df.loc[0, 'A'] = 999 # Change the first value in df
>>> df.head(1)
     A         B         C         D
0  999 -0.742688 -1.980673 -0.920133
>>> df2.head(1) # df2 is unchanged. It not a view, it a copy!
          A         C
0  0.251262 -1.980673

Обратите внимание, что это также относится к методу @piggybox. (Хотя этот метод приятный и гладкий и Pythonic. Я не делаю это!)

Подробнее о просмотрах и копиях см. этот ответ SO и эта часть Pandas docs, на которые ссылается этот ответ.

Ответ 8

Аналогичным образом, при чтении файла может потребоваться исключить столбцы заранее, вместо того, чтобы расточительно считывать ненужные данные в память и затем отбрасывать их.

Начиная с панд 0.20.0, usecols теперь принимает вызываемые usecols. 1 Это обновление предоставляет более гибкие возможности для чтения столбцов:

skipcols = [...]
read_csv(..., usecols=lambda x: x not in skipcols)

Последний шаблон по сути является обратным традиционному методу usecols - пропускаются только указанные столбцы.


Дано

Данные в файле

import numpy as np
import pandas as pd


df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

filename = "foo.csv"
df.to_csv(filename)

Код

skipcols = ["B", "D"]
df1 = pd.read_csv(filename, usecols=lambda x: x not in skipcols, index_col=0)
df1

Выход

          A         C
0  0.062350  0.076924
1 -0.016872  1.091446
2  0.213050  1.646109
3 -1.196928  1.153497
4 -0.628839 -0.856529
...

подробности

DataFrame был записан в файл. Затем он считывался как отдельный DataFrame, теперь пропуская ненужные столбцы (B и D).

Обратите внимание, что для ситуации OP, поскольку данные уже созданы, лучшим подходом является принятый ответ, который удаляет ненужные столбцы из существующего объекта. Тем не менее, техника, представленная здесь, наиболее полезна при непосредственном считывании данных из файлов в DataFrame.

В этом выпуске был подан запрос на вариант "пропуска", который был рассмотрен в более позднем выпуске.

Ответ 9

У вас есть 4 столбца A, B, C, D

Вот лучший способ выбрать столбцы, необходимые для нового кадра данных: -

df2 = df1[['A','D']]

если вы хотите использовать вместо этого номера столбцов, используйте: -

df2 = df1[[0,3]]