选择/排除pandas中的列集

时间:2013-02-18 16:22:39

标签: python pandas dataframe

我想根据列选择从现有数据框创建视图或数据框。

例如,我想从数据框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]

我做错了什么?也许更一般地说,大熊猫有哪些机制来支持数据框中任意列集的选择和排除

9 个答案:

答案 0 :(得分:289)

您可以删除不需要的列或选择您需要的列

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

答案 1 :(得分:118)

有一种名为difference的新索引方法。它返回原始列,并删除作为参数传递的列。

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

此处,输出用于从B过滤掉Ddf列。

答案 2 :(得分:58)

您根本不需要将其转换为集合:

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

答案 3 :(得分:19)

另一个选项,无需拖放或循环过滤:

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

答案 4 :(得分:14)

另请查看内置的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 :(得分: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]

答案 6 :(得分:4)

以下是如何创建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's not a view, it's a copy!
          A         C
0  0.251262 -1.980673

另请注意,@ piggybox的方法也是如此。 (虽然这种方法很好,很光滑和Pythonic。我不会这样做!!)

有关观看次数与副本的详细信息,请参阅该答案所指的this SO answerthis part of the Pandas docs

答案 7 :(得分:2)

与此类似,在阅读文件时,可能希望先排除列,而不是浪费地将不需要的数据读入内存,然后丢弃它们。

截至pandas 0.20.0,usecols now accepts callables 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读回,现在跳过不需要的列(BD)。

请注意,对于OP的情况,由于已经创建了数据,因此更好的方法是接受的答案,它会从现有对象中删除不需要的列。但是,当直接将文件中的数据读入DataFrame时,此处介绍的技术非常有用。

针对this issue中的“skipcols”选项提出了一个请求,并在稍后的issue中进行了解决。

答案 8 :(得分:2)

您有4列A,B,C,D

以下是选择新数据框所需列的更好方法: -

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

如果您希望使用列号,请使用: -

df2 = df1[[0,3]]