在pandas数据框中选择多个列

use*_*440 938 python select dataframe pandas

我有不同列中的数据,但我不知道如何提取它以将其保存在另一个变量中.

index  a   b   c
1      2   3   4
2      3   4   5
Run Code Online (Sandbox Code Playgroud)

我该如何选择'a','b'并保存到DF1?

我试过了

df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']
Run Code Online (Sandbox Code Playgroud)

似乎没有工作.

ely*_*ely 1521

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

在这里你有几个选择.如果您从上下文中了解要切出哪些变量,则只需通过将列表传递给__getitem__语法([]的)来返回仅包含这些列的视图.

df1 = df[['a','b']]
Run Code Online (Sandbox Code Playgroud)

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

df1 = df.iloc[:,0:2] # Remember that Python does not slice inclusive of the ending index.
Run Code Online (Sandbox Code Playgroud)

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

但是,有时候,Pandas中的索引约定不会执行此操作,而是为您提供一个新变量,它只引用与原始对象中的子对象或切片相同的内存块.这将通过第二种索引方式发生,因此您可以使用该copy()函数对其进行修改以获得常规副本.发生这种情况时,更改您认为切片对象的内容有时会改变原始对象.总是很高兴看到这个.

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

  • 注意:`df [['a','b']]`生成一个副本 (166认同)
  • `ix`接受切片参数,因此您也可以获取列.例如,`df.ix [0:2,0:2]`获取左上角的2x2子数组,就像它对NumPy矩阵一样(当然,取决于你的列名).您甚至可以在列的字符串名称上使用切片语法,例如`df.ix [0,'Col1':'Col5']`.这样就可以在``df.columns`数组中的`Col1`和`Col5`之间排序所有列.说'ix`索引行是不正确的.这只是它最基本的用途.它还支持更多索引.所以,`ix`对于这个问题是完全一般的. (9认同)
  • @AndrewCassidy再也不要使用.ix了.如果你想用整数切片,可以使用`.iloc`,它不像Python列表那样排除最后一个位置. (7认同)
  • @dte324 如果您的 DataFrame 名为“df”,则使用“df.iloc[:, [1, 4]]”。通常,如果您想要这种类型的访问模式,您已经知道这些特定的列名称,并且您可以使用 `df.loc[:, ['name2', 'name5']]` 其中 `'name2'` 和`'name5'` 是您想要的相应列的列字符串名称,或者使用例如 `name2 = df.columns[1]` 查找名称。 (5认同)

hob*_*obs 101

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

newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The "3rd" entry is at slot 2.
Run Code Online (Sandbox Code Playgroud)

作为EMS在指出他的答案,df.ix更多的片列有点简洁,但.columns切割界面可能因为它使用了香草1-d Python列表索引/切片语法更加自然.

警告:列'index'是一个坏名称DataFrame.同一标签也用于真实df.index属性,一个Index数组.因此返回您的列,并返回df['index']真正的DataFrame索引df.index.An Index是一种特殊的Series优化类型,用于查找元素的值.对于df.index,它用于按标签查找行.该df.columns属性也是一个pd.Index数组,用于按标签查找列.

  • 正如我在上面的评论中指出的那样,`.ix`对于行来说不是*.它用于通用切片,可用于多维切片.它基本上只是NumPy通常的`__getitem__`语法的接口.也就是说,只需应用转置操作`df.T`,就可以轻松地将列切片问题转换为行切片问题.你的例子使用`columns [1:3]`,这有点误导.`columns`的结果是`Series`; 小心不要像对待数组一样对待它.此外,您应该将其更改为`columns [2:3]`以匹配您的"第3和第4"注释. (3认同)
  • 请注意弃用警告:.ix已弃用.因此这是有道理的:newdf = df [df.columns [2:4]] (2认同)

ayh*_*han 100

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

df.loc[:, 'C':'E']
Run Code Online (Sandbox Code Playgroud)

相当于

df[['C', 'D', 'E']]  # or df.loc[:, ['C', 'D', 'E']]
Run Code Online (Sandbox Code Playgroud)

并返回列C通过E.


关于随机生成的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
Run Code Online (Sandbox Code Playgroud)

要获取从C到E的列(请注意,与整数切片不同,列中包含"E"):

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
...
Run Code Online (Sandbox Code Playgroud)

同样适用于根据标签选择行.从这些列获取行'R6'到'R10':

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
Run Code Online (Sandbox Code Playgroud)

.loc还接受一个布尔数组,以便您可以选择数组中相应条目所在的列True.例如,df.columns.isin(list('BCD'))return array([False, True, True, True, False, False], dtype=bool)- 如果列名在列表中['B', 'C', 'D'],则为True ; 错,否则.

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
...
Run Code Online (Sandbox Code Playgroud)


Wes*_*ney 60

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
Run Code Online (Sandbox Code Playgroud)

  • `df [['b','c']].rename(columns = {'b':'foo','c':'bar'})` (3认同)

zer*_*tor 52

我意识到这个问题已经很老了,但在最新版本的熊猫中,有一种简单的方法可以做到这一点.列名(字符串)可以按照您喜欢的方式进行切片.

columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)
Run Code Online (Sandbox Code Playgroud)

  • 这只能在创建时完成.问题是询问您是否已在数据框中拥有它. (5认同)

小智 20

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

只是说

colsToDrop = ['a']
df.drop(colsToDrop, axis=1)
Run Code Online (Sandbox Code Playgroud)

只返回列b和的DataFrame c.

这里drop记录该方法.


Ram*_*kov 19

您可以使用该pandas.DataFrame.filter方法来过滤或重新排序列,如下所示:

df1 = df.filter(['a', 'b'])
Run Code Online (Sandbox Code Playgroud)

这在链接方法时也非常有用。

  • “filter”很棒,但并不像应有的那样广为人知。特别是,您还可以使用如下正则表达式:`df.filter(regex='a|b')`。我在回答这个问题时有一个更长的例子:/sf/ask/2046928551/ (2认同)
  • 过滤器还能够忽略“items=..list”中不存在的列,这有时非常有用! (2认同)

Alv*_*vis 18

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

# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]
Run Code Online (Sandbox Code Playgroud)

更多细节可以在这里找到

  • 那将是“surveys_df.iloc [:, [2,5]]”。 (2认同)

Viv*_*han 11

有了熊猫,

机智列名称

dataframe[['column1','column2']]
Run Code Online (Sandbox Code Playgroud)

使用iloc,可以使用列索引

dataframe[:,[1,2]]
Run Code Online (Sandbox Code Playgroud)

可以使用loc列名称

dataframe[:,['column1','column2']]
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你 !


pin*_*ash 9

您可以使用熊猫。我创建了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'])
Run Code Online (Sandbox Code Playgroud)

数据框:

           Test_1  Test_2  Test_3
    Jane        1       2       5
    Peter       5       4       5
    Alex        7       7       8
    Ann         7       6       9
Run Code Online (Sandbox Code Playgroud)

要按名称选择1列或更多列:

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

           Test_1  Test_3
    Jane        1       5
    Peter       5       5
    Alex        7       8
    Ann         7       9
Run Code Online (Sandbox Code Playgroud)

您还可以使用:

    df.Test_2
Run Code Online (Sandbox Code Playgroud)

和哟列 Test_2

    Jane     2
    Peter    4
    Alex     7
    Ann      6
Run Code Online (Sandbox Code Playgroud)

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

    df.loc[:,'Test_1':'Test_3']
Run Code Online (Sandbox Code Playgroud)

“切片”为:

            Test_1  Test_2  Test_3
     Jane        1       2       5
     Peter       5       4       5
     Alex        7       7       8
     Ann         7       6       9
Run Code Online (Sandbox Code Playgroud)

如果你只是想PeterAnn来自列Test_1Test_3

    df.loc[['Peter', 'Ann'],['Test_1','Test_3']]
Run Code Online (Sandbox Code Playgroud)

你得到:

           Test_1  Test_3
    Peter       5       5
    Ann         7       9
Run Code Online (Sandbox Code Playgroud)


cot*_*ail 8

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

  • 基于标签:[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)]

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

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
Run Code Online (Sandbox Code Playgroud)

旧答案:

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

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

由于这会默认创建一个副本,因此您不会遇到麻烦SettingWithCopyWarning


xs()可用于按标签选择列(必须通过系列/数组/索引)。

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

资源1

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

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)
Run Code Online (Sandbox Code Playgroud)

资源2


W.P*_*rin 7

如果你想逐行获取一个元素索引和列名,你可以这样做df['b'][0].它就像你可以想象一样简单.

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

注意:由于v0.20 ix已被弃用而支持loc/ iloc.


toz*_*CSS 7

从0.21.0开始,不推荐使用.loc[]使用带有一个或多个缺少标签的列表,而推荐使用.reindex。因此,您的问题的答案是:

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

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

索引和选择数据中了解更多信息


Bip*_*Das 7

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
Run Code Online (Sandbox Code Playgroud)


小智 7

要从数据帧 df 中选择列“a”和“b”并将它们保存到新的数据帧 df1 中,可以在 Python 中使用以下方法:

方法 1:使用列索引

df1 = df[['a', 'b']]
Run Code Online (Sandbox Code Playgroud)

方法 2:使用 loc 访问器

df1 = df.loc[:, ['a', 'b']]
Run Code Online (Sandbox Code Playgroud)

方法 3:使用 iloc 访问器

df1 = df.iloc[:, [1, 2]]
Run Code Online (Sandbox Code Playgroud)

方法四:使用过滤功能

df1 = df.filter(['a', 'b'])
Run Code Online (Sandbox Code Playgroud)

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

df1 = df.loc[:, df.columns.isin(['a', 'b'])].copy()
Run Code Online (Sandbox Code Playgroud)

方法六:使用reindex方法

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

Run Code Online (Sandbox Code Playgroud)


Har*_*hit 6

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

pandas.DataFrame.drop()当然是根据用户定义的列列表对数据进行子集化的选项(尽管您必须小心始终使用数据帧的副本,并且不应该将就地参数设置为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)
Run Code Online (Sandbox Code Playgroud)

输出将是:

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)
Run Code Online (Sandbox Code Playgroud)


Ank*_*ita 6

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

使用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()
Run Code Online (Sandbox Code Playgroud)

  • [请不要推荐使用iterrows()。](/sf/answers/3889043091/)它是熊猫历史上最糟糕的反模式的公然推动者。 (5认同)
  • 恕我直言,iterrows() 应该是使用 pandas 时的最后一个选项。 (2认同)

小智 6

尝试使用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'])
Run Code Online (Sandbox Code Playgroud)


Pun*_*nha 5

您还可以使用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
Run Code Online (Sandbox Code Playgroud)

请使用df.pop(c)