在pandas数据框中选择多个列

时间:2012-07-01 21:03:17

标签: python pandas dataframe select

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

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

如何选择'a''b'并将其保存到df1?

我试过

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

似乎无效。

23 个答案:

答案 0 :(得分:1266)

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

这里有几个选项。如果您从上下文中了解要切出哪些变量,则只需通过将列表传递到__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

要使用iloc,您需要知道列位置(或索引)。由于列位置可能会发生变化,而不是硬编码索引,您可以使用iloc以及get_loc数据框对象方法的columns函数来获取列索引。

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

现在,您可以使用此字典通过名称和iloc访问列。

答案 1 :(得分:90)

假设您的列名称(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.

正如EMS在his answer中指出的那样,df.ix更简洁地对列进行切片,但.columns切片界面可能更自然,因为它使用了vanilla 1-D python列表索引/切片语法。

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

答案 2 :(得分:87)

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

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

相当于

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

并通过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

要获取从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
...

同样适用于根据标签选择行。获取行' 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

.loc也接受布尔数组,因此您可以选择数组中相应条目为True的列。例如,df.columns.isin(list('BCD'))返回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
...

答案 3 :(得分:57)

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

答案 4 :(得分:47)

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

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

答案 5 :(得分:20)

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

只是说

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

会返回一个只包含bc列的DataFrame。

drop方法记录在案here

答案 6 :(得分:17)

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

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

可以找到更多详细信息here

答案 7 :(得分:12)

只需使用: 它将选择b和c列。

df1=pd.DataFrame()
df1=df[['b','c']]

然后你可以调用df1:

df1

答案 8 :(得分:11)

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

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

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

答案 9 :(得分:7)

有了熊猫,

机智列名

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

使用iloc,可以像使用列索引一样

dataframe[:,[1,2]]
带有loc列名称的

可以像

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

希望有帮助!

答案 10 :(得分:6)

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

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

注意:由于v0.20 ix已被弃用,而不是loc / iloc

答案 11 :(得分:4)

以上响应中讨论的不同方法基于以下假设:用户要么知道要删除的列索引或要子集的列索引,要么用户希望使用一定范围的列(例如'C':' E')。 pandas.DataFrame.drop()当然是基于用户定义的列列表对数据进行子集化的选项(尽管您必须谨慎使用始终使用dataframe的副本和 inplace < / em>参数不应设置为 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

答案 12 :(得分:4)

下面是我的代码:

import pandas as pd
df = pd.read_excel("data.xlsx", sheet_name = 2)
print df
df1 = df[['emp_id','date']]
print df1

输出:

  emp_id        date  count
0   1001   11/1/2018      3
1   1002   11/1/2018      4
2          11/2/2018      2
3          11/3/2018      4
  emp_id        date
0   1001   11/1/2018
1   1002   11/1/2018
2          11/2/2018
3          11/3/2018

第一个数据帧是主数据帧。我只是将两列复制到df1中。

答案 13 :(得分:3)

另一种简单的方法:迭代行

使用同伴

`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()

答案 14 :(得分:3)

尝试使用pandas.DataFrame.get(请参阅docs

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

答案 15 :(得分:2)

您可以使用熊猫。 我创建了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'])

DataFrame:

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

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

    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_1列到Test_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

如果您只想从PeterAnn列中访问Test_1Test_3

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

您得到:

           Test_1  Test_3
    Peter       5       5
    Ann         7       9

答案 16 :(得分:2)

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

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

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

更多信息,请访问Indexing and Selecting Data

答案 17 :(得分:2)

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

就用这个功能

答案 18 :(得分:2)

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

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

选择除一列之外的所有列:

df[df.columns.drop('C')]

输出:

   A   B     D
0  1  10  1000
1  2  20  2000

选择除两个之外的所有:

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

输出:

   A    C
0  1  100
1  2  200

答案 19 :(得分:1)

您还可以使用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)

答案 20 :(得分:1)

500ms

答案 21 :(得分:0)

我已经看到了一些答案,但是仍然不清楚。您将如何选择那些感兴趣的列?答案是,如果将它们收集在列表中,则可以使用列表引用列。

示例

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

我有以下列表/ numpy数组extracted_features,指定了63列。原始数据集有103列,我想准确地提取出这些列,然后我将使用

dataset[extracted_features]

然后您将得到这个

enter image description here

您将在机器学习中(特别是在功能选择中)经常使用此功能。我也想讨论其他方法,但是我认为其他stackoverflowers已经对此进行了讨论。希望对您有所帮助!

答案 22 :(得分:0)

要选择多个列,请随后提取并查看它们:df以前被命名为数据框,而不是创建新的数据框df1,然后选择要提取和查看的A到D列

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

所有必填列都会显示!