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

例如,我想从一个dataframe df1中创建一个dataframe df2,该dataframe 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]

我做错了什么?也许更普遍的是,熊猫必须有什么机制来支持从数据框架中选择和排除任意列集?


当前回答

下面是如何创建一个不包含列列表的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。我不会这么做的!!)

有关视图与副本的更多信息,请参阅这个SO答案和这个答案所指向的Pandas文档的这一部分。

其他回答

你不需要把它转换成一个集合:

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

有一种新的索引方法叫做差。它返回原始列,作为参数传递的列被删除。

这里,结果用于从df中删除列B和D:

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

注意,这是一个基于集合的方法,因此重复的列名会导致问题,而且列的顺序可能会改变。


与drop相比的优点:当您只需要列列表时,您不需要创建整个数据框架的副本。例如,为了在列的子集上删除重复项:

# may create a copy of the dataframe
subset = df.drop(['B', 'D'], axis=1).columns

# does not create a copy the dataframe
subset = df.columns.difference(['B', 'D'])

df = df.drop_duplicates(subset=subset)

你有四列A B C D

这里有一个更好的方法来选择你需要为新的数据框架的列:-

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

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

df2 = df1[[0,3]]

另一个选项,不需要在循环中删除或过滤:

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

# or even simpler since 0.24
# with the caveat that it reorders columns alphabetically 
df[df.columns.difference(['C', 'D'])]

你只需要把你的集合转换成一个列表

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]