关于python:在pandas数据框中选择多个列

Selecting multiple columns in a pandas dataframe

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

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

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

我试过

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

似乎都不管用。


列名称(字符串)不能按您尝试的方式切片。

这里有几个选择。如果您从上下文中知道要分割哪些变量,那么只需将一个列表传递到__getitem__语法(the[]s)中,就可以返回这些列的视图。

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

或者,如果重要的是用数字索引它们,而不是用它们的名称索引(比如说,您的代码应该在不知道前两列的名称的情况下自动进行索引),那么您可以这样做:

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

此外,您应该熟悉查看熊猫对象和复制该对象的想法。上述第一个方法将在内存中返回所需子对象(所需切片)的新副本。

但是,有时在panda中有索引约定,它们不这样做,而是为您提供一个新的变量,该变量只引用与原始对象中的子对象或切片相同的内存块。这将通过第二种索引方式实现,因此您可以使用copy()函数对其进行修改,以获得常规副本。当发生这种情况时,更改您认为是切片对象的内容有时会更改原始对象。总是很好的注意这个。

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

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

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

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


假设您的列名(df.columns['index','a','b','c']的话,那么您需要的数据就在第3列和第4列。如果在脚本运行时不知道它们的名称,可以这样做

1
newdf = df[df.columns[2:4]] # Remember, Python is 0-offset! The"3rd" entry is at slot 2.

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

警告:'index'DataFrame列的坏名称。同样的标签也用于实际的df.index属性,即Index数组。所以您的列由df['index']返回,实际的数据帧索引由df.index返回。Index是一种特殊的Series类型,为查找元素值而优化。对于df.index,它是用来按标签查找行的。该df.columns属性也是一个pd.Index数组,用于按列的标签查找列。


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

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

相当于

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

并返回从cE的列。

随机生成的数据帧上的演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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"):

1
2
3
4
5
6
7
8
9
10
11
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":

1
2
3
4
5
6
7
8
9
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的列。例如,如果列名在['B', 'C', 'D']列表中,则df.columns.isin(list('BCD'))返回array([False, True, True, True, False, False], dtype=bool)true;否则返回false。

1
2
3
4
5
6
7
8
9
10
11
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
...

1
2
3
4
5
6
7
8
9
10
11
12
13
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


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

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


您可以提供一个要删除的列列表,并返回数据帧,其中只包含在熊猫数据帧上使用drop()函数所需的列。

只是说

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

将返回仅包含列b和列c的数据帧。

这里记录了drop方法。


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

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

这里可以找到更多详细信息


只需使用:它将选择B和C列。

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

然后你可以打电话给DF1:

1
df1

和熊猫一起,

WIT列名

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

使用iLoc,列索引可以像

1
dataframe[:,[1,2]]

使用loc列名称可以像

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

希望它有帮助!


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

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

注:由于v0.20,ix已被否决,赞成loc/iloc


上述响应中讨论的不同方法基于这样的假设:要么用户知道要删除的列索引,要么用户希望使用一系列列(例如"c":"e")对数据帧进行子集。pandas.dataframe.drop()当然是根据用户定义的列列表对数据进行子集的一个选项(尽管您必须小心,始终使用数据帧副本,但不应将inplace参数设置为true!!)

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

1
2
3
4
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


以下是我的代码:

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

输出:

1
2
3
4
5
6
7
8
9
10
  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中。


我非常肯定这不是一个优化的方法,但可以被视为一个不同的方法。

使用迭代

1
2
3
4
5
`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()

你可以用熊猫。我创建数据帧:

1
2
3
4
    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:

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

按名称选择一列或多列:

1
2
3
4
5
6
7
    df[['Test_1','Test_3']]

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

您还可以使用:

1
    df.Test_2

然后你得到EDOCX1列〔13〕。

1
2
3
4
    Jane     2
    Peter    4
    Alex     7
    Ann      6

您还可以使用.loc()从这些行中选择列和行。这叫做"切片"。注意,我从EDOCX1列(15)到EDOCX1列(16)

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

"切片"是:

1
2
3
4
5
            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列:

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

你得到:

1
2
3
           Test_1  Test_3
    Peter       5       5
    Ann         7       9

从0.21.0开始,使用带有一个或多个缺少标签的列表的.loc[]被否决,而倾向于.reindex。所以,你的问题的答案是:

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

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

阅读有关索引和选择数据的更多信息


您也可以使用df.pop()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> 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)