在 Pandas 数据帧中选择多个列

Selecting multiple columns in a Pandas dataframe

提问人:user1234440 提问时间:7/2/2012 最后编辑:cottontailuser1234440 更新时间:11/4/2023 访问量:3895719

问:

如何选择列和 从中 并将它们保存到新的 DataFrame 中?abdfdf1

index  a   b   c
1      2   3   4
2      3   4   5

尝试不成功:

df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']
Python Pandas DataFrame 选择 索引

评论


答:

2655赞 ely 7/2/2012 #1

列名(字符串)无法以您尝试的方式进行切片。

在这里,您有几个选择。如果您从上下文中知道要切出哪些变量,则可以通过将列表传递到__getitem__语法([])中来仅返回这些列的视图。

df1 = df[['a', 'b']]

或者,如果以数字而不是名称方式索引它们很重要(比如说你的代码应该在不知道前两列的名称的情况下自动执行此操作),那么你可以改为这样做:

df1 = df.iloc[:, 0:2] # Remember that Python does not slice inclusive of the ending index.

此外,您应该熟悉 Pandas 对象视图与该对象副本的概念。上述第一种方法将在所需子对象(所需切片)的内存中返回一个新副本。

但是,有时 Pandas 中的索引约定不会这样做,而是为您提供一个新变量,该变量仅引用与原始对象中的子对象或切片相同的内存块。第二种索引方式将发生这种情况,因此您可以使用该方法对其进行修改以获取常规副本。发生这种情况时,更改您认为是切片对象的内容有时会更改原始对象。留意这一点总是好的。.copy()

df1 = df.iloc[0, 0:2].copy() # To avoid the case where changing df1 also changes df

要使用 ,您需要知道列位置(或索引)。由于列位置可能会发生变化,因此可以与 DataFrame 对象的方法一起使用来获取列索引,而不是硬编码索引。ilocilocget_loccolumns

{df.columns.get_loc(c): c for idx, c in enumerate(df.columns)}

现在,您可以使用此字典通过名称和使用 .iloc

评论

295赞 Wes McKinney 7/9/2012
注意:生成副本df[['a','b']]
79赞 Wes McKinney 7/9/2012 #2
In [39]: df
Out[39]: 
   index  a  b  c
0      1  2  3  4
1      2  3  4  5

In [40]: df1 = df[['b', 'c']]

In [41]: df1
Out[41]: 
   b  c
0  3  4
1  4  5

评论

0赞 Peter Mortensen 2/8/2021
解释是有道理的。例如,要点是什么?您可以编辑您的答案 - 没有“编辑:”,“更新:”或类似内容 - 答案应该看起来就像今天写的一样。
142赞 hobs 11/1/2012 #3

假设您的列名 () 是 ,那么您想要的数据位于 第三列和第四列。如果在脚本运行时不知道他们的名字,可以执行此操作df.columns['index','a','b','c']

newdf = df[df.columns[2:4]] # Remember, Python is zero-offset! The "third" entry is at slot two.

正如 EMS 在他的回答中指出的那样,对列进行切片更简洁一些,但切片界面可能更自然,因为它使用了普通的一维 Python 列表索引/切片语法。df.ix.columns

警告:是列的错误名称。相同的标签也用于实际属性,即数组。因此,您的列由 返回,实际 DataFrame 索引由 返回。An 是一种特殊的类型,针对查找其元素的值进行了优化。对于 df.index,它用于按标签查找行。该属性也是一个数组,用于按标签查找列。'index'DataFramedf.indexIndexdf['index']df.indexIndexSeriesdf.columnspd.Index

29赞 Muthu Chithambara Jothi 9/3/2014 #4

您可以提供要删除的列列表,并使用 Pandas DataFrame 上的函数返回 DataFrame,其中仅包含所需的列。drop()

只是说

colsToDrop = ['a']
df.drop(colsToDrop, axis=1)

将返回一个仅包含列和 的 DataFrame。bc

此处记录了该方法。drop

96赞 zerovector 2/4/2016 #5

在最新版本的 Pandas 中,有一种简单的方法可以做到这一点。列名(字符串)可以按照您喜欢的任何方式进行切片。

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)
279赞 ayhan 4/30/2016 #6

从版本 0.11.0 开始,可以按照您尝试使用 .loc 索引器的方式对列进行切片:

df.loc[:, 'C':'E']

相当于

df[['C', 'D', 'E']]  # or df.loc[:, ['C', 'D', 'E']]

并通过 返回列。CE


关于随机生成的 DataFrame 的演示:

import pandas as pd
import numpy as np
np.random.seed(5)
df = pd.DataFrame(np.random.randint(100, size=(100, 6)),
                  columns=list('ABCDEF'),
                  index=['R{}'.format(i) for i in range(100)])
df.head()

Out:
     A   B   C   D   E   F
R0  99  78  61  16  73   8
R1  62  27  30  80   7  76
R2  15  53  80  27  44  77
R3  75  65  47  30  84  86
R4  18   9  41  62   1  82

要从 to 获取列(请注意,与整数切片不同,列中包含列):CEE

df.loc[:, 'C':'E']

Out:
      C   D   E
R0   61  16  73
R1   30  80   7
R2   80  27  44
R3   47  30  84
R4   41  62   1
R5    5  58   0
...

这同样适用于根据标签选择行。从这些列中获取要的行:R6R10

df.loc['R6':'R10', 'C':'E']

Out:
      C   D   E
R6   51  27  31
R7   83  19  18
R8   11  67  65
R9   78  27  29
R10   7  16  94

.loc还接受一个 Boolean 数组,因此您可以选择数组中对应条目为 的列。例如,如果列名在列表中,则返回 - True;否则为 False。Truedf.columns.isin(list('BCD'))array([False, True, True, True, False, False], dtype=bool)['B', 'C', 'D']

df.loc[:, df.columns.isin(list('BCD'))]

Out:
      B   C   D
R0   78  61  16
R1   27  30  80
R2   53  80  27
R3   65  47  30
R4    9  41  62
R5   78   5  58
...
25赞 Ali 5/2/2017 #7

我发现这种方法非常有用:

# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]

更多细节可以在这里找到。

10赞 W.Perrin 1/3/2018 #8

如果你想通过行索引和列名来获取一个元素,你可以像 一样做。它和你想象的一样简单。df['b'][0]

或者你可以使用 - 索引和标签的混合用法。df.ix[0,'b']

注意:从 v0.20 开始,已被弃用,取而代之的是 / 。ixlociloc

6赞 Harshit Lamba 7/22/2018 #9

前面的答案中讨论的不同方法基于这样的假设:用户知道要删除或子集的列索引,或者用户希望使用一系列列(例如,在“C”:“E”之间)对数据帧进行子集。

熊猫。DataFrame.drop() 当然是一个选项,可以根据用户定义的列列表对数据进行子集(尽管您必须注意始终使用 DataFrame 的副本,并且 inplace 参数不应设置为 True!!)

另一种选择是使用 pandas.columns.difference(),它对列名进行设置差异,并返回包含所需列的数组的索引类型。以下是解决方案:

df = pd.DataFrame([[2,3,4], [3,4,5]], columns=['a','b','c'], index=[1,2])
columns_for_differencing = ['a']
df1 = df.copy()[df.columns.difference(columns_for_differencing)]
print(df1)

输出将为:

    b   c
1   3   4
2   4   5
25赞 tozCSS 8/16/2018 #10

从 0.21.0 开始,不推荐使用或使用缺少一个或多个标签的列表,取而代之的是 。所以,你的问题的答案是:.loc[].reindex

df1 = df.reindex(columns=['b','c'])

在以前的版本中,只要找到至少一个键,使用 就可以工作(否则它会引发 )。此行为已弃用,现在显示一条警告消息。推荐的替代方法是使用 。.loc[list-of-labels]KeyError.reindex()

有关详细信息,请参阅索引和选择数据

7赞 Ankita 10/15/2018 #11

一种不同且简单的方法:迭代行

使用 iterows

 df1 = pd.DataFrame() # Creating an empty dataframe
 for index,i in df.iterrows():
    df1.loc[index, 'A'] = df.loc[index, 'A']
    df1.loc[index, 'B'] = df.loc[index, 'B']
    df1.head()
54赞 Wickkiey 11/21/2018 #12

与熊猫一起,

WIT 列名称

dataframe[['column1','column2']]

要按 iloc 和带有索引号的特定列进行选择,请执行以下操作:

dataframe.iloc[:,[1,2]]

与 loc 列名一起使用,例如

dataframe.loc[:,['column1','column2']]
5赞 Puneet Sinha 1/29/2019 #13

你也可以使用 df.pop():

>>> df = pd.DataFrame([('falcon', 'bird',    389.0),
...                    ('parrot', 'bird',     24.0),
...                    ('lion',   'mammal',   80.5),
...                    ('monkey', 'mammal', np.nan)],
...                   columns=('name', 'class', 'max_speed'))
>>> df
     name   class  max_speed
0  falcon    bird      389.0
1  parrot    bird       24.0
2    lion  mammal       80.5
3  monkey  mammal

>>> df.pop('class')
0      bird
1      bird
2    mammal
3    mammal
Name: class, dtype: object

>>> df
     name  max_speed
0  falcon      389.0
1  parrot       24.0
2    lion       80.5
3  monkey        NaN

请使用 .df.pop(c)

14赞 pink.slash 2/20/2019 #14

您可以使用 Pandas。

我创建 DataFrame:

import pandas as pd
df = pd.DataFrame([[1, 2,5], [5,4, 5], [7,7, 8], [7,6,9]],
                  index=['Jane', 'Peter','Alex','Ann'],
                  columns=['Test_1', 'Test_2', 'Test_3'])

数据帧:

       Test_1  Test_2  Test_3
Jane        1       2       5
Peter       5       4       5
Alex        7       7       8
Ann         7       6       9

要按名称选择一列或多列,请执行以下操作:

df[['Test_1', 'Test_3']]

       Test_1  Test_3
Jane        1       5
Peter       5       5
Alex        7       8
Ann         7       9

您还可以使用:

df.Test_2

你得到列:Test_2

Jane     2
Peter    4
Alex     7
Ann      6

您还可以使用 .loc() 从这些行中选择列和行。这称为“切片”。请注意,我从列到:Test_1Test_3

df.loc[:, 'Test_1':'Test_3']

“切片”是:

       Test_1  Test_2  Test_3
Jane        1       2       5
Peter       5       4       5
Alex        7       7       8
Ann         7       6       9

如果你只是想要和从列和:PeterAnnTest_1Test_3

df.loc[['Peter', 'Ann'], ['Test_1', 'Test_3']]

您将获得:

       Test_1  Test_3
Peter       5       5
Ann         7       9
4赞 KareemJ 5/27/2019 #15

我已经看到了几个答案,但有一个我仍然不清楚。您将如何选择这些感兴趣的列?

答案是,如果您将它们收集在一个列表中,则可以使用列表引用列。

print(extracted_features.shape)
print(extracted_features)

(63,)
['f000004' 'f000005' 'f000006' 'f000014' 'f000039' 'f000040' 'f000043'
 'f000047' 'f000048' 'f000049' 'f000050' 'f000051' 'f000052' 'f000053'
 'f000054' 'f000055' 'f000056' 'f000057' 'f000058' 'f000059' 'f000060'
 'f000061' 'f000062' 'f000063' 'f000064' 'f000065' 'f000066' 'f000067'
 'f000068' 'f000069' 'f000070' 'f000071' 'f000072' 'f000073' 'f000074'
 'f000075' 'f000076' 'f000077' 'f000078' 'f000079' 'f000080' 'f000081'
 'f000082' 'f000083' 'f000084' 'f000085' 'f000086' 'f000087' 'f000088'
 'f000089' 'f000090' 'f000091' 'f000092' 'f000093' 'f000094' 'f000095'
 'f000096' 'f000097' 'f000098' 'f000099' 'f000100' 'f000101' 'f000103']

我有以下 list/NumPy 数组 ,指定 63 列。原始数据集有 103 列,我想准确地提取这些列,然后我会使用extracted_features

dataset[extracted_features]

你最终会得到这个

Enter image description here

这是您在机器学习中经常使用的东西(更具体地说,在特征选择中)。我也想讨论其他方法,但我认为其他 Stack Overflower 用户已经涵盖了这一点。

38赞 Ramin Melikov 4/21/2020 #16

您可以使用该方法对列进行筛选或重新排序,如下所示:pandas.DataFrame.filter

df1 = df.filter(['a', 'b'])

当您链接方法时,这也非常有用。

9赞 Biplob Das 5/19/2020 #17
df[['a', 'b']]  # Select all rows of 'a' and 'b'column 
df.loc[0:10, ['a', 'b']]  # Index 0 to 10 select column 'a' and 'b'
df.loc[0:10, 'a':'b']  # Index 0 to 10 select column 'a' to 'b'
df.iloc[0:10, 3:5]  # Index 0 to 10 and column 3 to 5
df.iloc[3, 3:5]  # Index 3 of column 3 to 5
9赞 Juan Miguel Díaz Pérez 8/3/2020 #18

尝试使用(参见文档):pandas.DataFrame.get

import pandas as pd
import numpy as np

dates = pd.date_range('20200102', periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
df.get(['A', 'C'])
4赞 Ivan Vrzogic 10/11/2020 #19

要选择多个列,请提取并查看它们: 是先前命名的数据框。然后创建一个新的数据框,并选择要提取和查看的列 A 到 D。dfdf1

df1 = pd.DataFrame(data_frame, columns=['Column A', 'Column B', 'Column C', 'Column D'])
df1

所有必填列都将显示!

0赞 Suleyman Suleymanzade 5/3/2021 #20
def get_slize(dataframe, start_row, end_row, start_col, end_col):
    assert len(dataframe) > end_row and start_row >= 0
    assert len(dataframe.columns) > end_col and start_col >= 0
    list_of_indexes = list(dataframe.columns)[start_col:end_col]
    ans = dataframe.iloc[start_row:end_row][list_of_indexes]
    return ans

只需使用此功能即可

评论

1赞 rubengavidia0x 1/27/2022
对我不起作用:TypeError:'int'和'str'的实例之间不支持'>'
4赞 Mykola Zotko 5/4/2021 #21

若要排除某些列,可以将它们放在列索引中。例如:

   A   B    C     D
0  1  10  100  1000
1  2  20  200  2000

选择除两个之外的所有选项:

df[df.columns.drop(['B', 'D'])]

输出:

   A    C
0  1  100
1  2  200

您还可以使用截断方法选择中间列:

df.truncate(before='B', after='C', axis=1)

输出:

    B    C
0  10  100
1  20  200
-2赞 Tusher 6/4/2022 #22

我认为这是实现目标的最简单方法。

import pandas as pd

cols = ['a', 'b']

df1 = pd.DataFrame(df, columns=cols)

df1 = df.iloc[:, 0:2]

评论

1赞 rachwa 8/6/2022
这已经在接受的答案中提出!此外,我不认为这是最简单的方法,因为您现在需要列的位置。
7赞 cottontail 4/10/2023 #23

尽管有很多方法可以选择多个列(使用列名列表或列索引列表):colsidx

  • 基于标签:、、、、、[cols].loc[:, cols].filter(cols).get(cols).reindex(cols, axis=1).xs(cols, axis=1)
  • 基于索引: ,.iloc[:, idx].take(idx, axis=1)
  • 切片:.iloc[:, 0:1].loc[:, 'col1':'col2'].truncate('col1', 'col2', axis=1)
  • 布尔索引: ,df.loc[:, pd.RangeIndex(df.shape[1])<2]df.loc[:, df.columns.isin(cols)]

在实践中,可能唯一值得记住的方法就是 或 方法,例如 .无论如何,选择多个列的所有方法都会创建一个副本。如果您担心,请在导入 pandas 后立即打开写入时复制模式(有关详细信息,请参阅此答案)。[cols]__getitem__(cols)df[['A', 'B']]SettingWithCopyWarning

pd.set_option('mode.copy_on_write', True)   # turn on copy-on-write

df = pd.DataFrame(0, range(5), [*'ABCD'])   # some initial dataframe
df1 = df[['A','C']]                         # select columns
df1['E'] = 1                                # no warnings, life's good

旧答案:

要按索引选择列,可以使用。take()

# select the first and third columns
df1 = df.take([0,2], axis=1)

由于默认情况下会创建一个副本,因此您不会对此感到讨厌。SettingWithCopyWarning


也可用于按标签选择列(必须传递 Series/array/Index)。xs()

# select columns A and B
df1 = df.xs(pd.Index(['A', 'B']), axis=1)

res1

最有用的方面是它可用于按级别选择 MultiIndex 列。xs

df2 = df.xs('col1', level=1, axis=1)

# can select specific columns as well
df3 = df.xs(pd.MultiIndex.from_tuples([('A', 'col1'), ('B', 'col2')]), axis=1)

res2

7赞 Prakash Edara 5/16/2023 #24

要从 dataframe df 中选择列 'a' 和 'b' 并将它们保存到新的 dataframe df1 中,您可以在 Python 中使用以下方法:

方法 1:使用列索引

df1 = df[['a', 'b']]

方法 2:使用 loc 访问器

df1 = df.loc[:, ['a', 'b']]

方法 3:使用 iloc 访问器

df1 = df.iloc[:, [1, 2]]

方法四:使用过滤功能

df1 = df.filter(['a', 'b'])

方法 5:使用具有布尔条件的 loc 访问器

df1 = df.loc[:, df.columns.isin(['a', 'b'])].copy()

方法 6:使用 reindex 方法

df1 = df.reindex(columns=['a', 'b'])

评论

0赞 Trenton McKinney 11/15/2023
似乎重复了大部分现有答案,因为这些方法已经包含在现有答案中。这似乎没有什么新东西。