在Pandas数据框中选择多列

如何从df中选择列ab,并将它们保存到新的数据框df1中?

index  a   b   c1      2   3   42      3   4   5

尝试失败:

df1 = df['a':'b']df1 = df.ix[:, 'a':'b']
3563128 次浏览

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

这里有几个选项。如果您从上下文中知道要切掉哪些变量,您可以通过将列表传递给#0语法([]'s)来仅返回这些列的视图。

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和数据框对象columns方法的get_loc函数来获取列索引,而不是硬编码索引。

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

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

In [39]: dfOut[39]:index  a  b  c0      1  2  3  41      2  3  4  5
In [40]: df1 = df[['b', 'c']]
In [41]: df1Out[41]:b  c0  3  41  4  5

假设您的列名(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在他的回答中指出的那样,df.ix对列进行了更简洁的切片,但.columns的切片接口可能更自然,因为它使用了普通的一维Python列表索引/切片语法。

DataFrame0:'index'对于DataFrame列来说是一个不好的名字。同样的标签也用于真正的df.index属性,一个Index数组。所以你的列由df['index']返回,真正的DataFrame索引由df.index返回。Index是一种特殊的Series,针对查找其元素的值进行了优化。df.index它用于通过标签查找行。df.columns属性也是一个pd.Index数组,用于通过标签查找列。

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

只是说说而已

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

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

drop方法记录在这里中。

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

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

从0.11.0版开始,列可以以您尝试使用#0索引器的方式切片:

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

获取与

df[['C', 'D', 'E']] # Mind, this makes a copy.

df.loc[:, ['C', 'D', 'E']] # This does not make a copy (better).

并返回列CE


随机生成的DataFrame上的演示:

import pandas as pdimport numpy as npnp.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   FR0  99  78  61  16  73   8R1  62  27  30  80   7  76R2  15  53  80  27  44  77R3  75  65  47  30  84  86R4  18   9  41  62   1  82

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

df.loc[:, 'C':'E']
Out:C   D   ER0   61  16  73R1   30  80   7R2   80  27  44R3   47  30  84R4   41  62   1R5    5  58   0...

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

df.loc['R6':'R10', 'C':'E']
Out:C   D   ER6   51  27  31R7   83  19  18R8   11  67  65R9   78  27  29R10   7  16  94

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

df.loc[:, df.columns.isin(list('BCD'))]
Out:B   C   DR0   78  61  16R1   27  30  80R2   53  80  27R3   65  47  30R4    9  41  62R5   78   5  58...

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

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

更多细节可以查看这里

如果您想通过行索引和列名获取一个元素,您可以像df['b'][0]一样执行此操作。它就像您想象的那样简单。

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

备注:从v0.20开始,ix已被弃用,转而支持loc/iloc

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

pandas.DataFrame.drop()当然是基于用户定义的列列表子集数据的选项(尽管你必须小心,你总是使用dataframe的副本,到位参数不应该设置为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   c1   3   42   4   5

从0.21.0开始,不建议将.loc[]与具有一个或多个缺失标签的列表一起使用,而支持.reindex。所以,你问题的答案是:

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

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

阅读更多索引和选择数据

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

使用迭代

 df1 = pd.DataFrame() # Creating an empty dataframefor index,i in df.iterrows():df1.loc[index, 'A'] = df.loc[index, 'A']df1.loc[index, 'B'] = df.loc[index, 'B']df1.head()

熊猫,

wit列名

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

按iloc和具有索引号的特定列进行选择:

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

使用loc列名可以像

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

您也可以使用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'))>>> dfname   class  max_speed0  falcon    bird      389.01  parrot    bird       24.02    lion  mammal       80.53  monkey  mammal
>>> df.pop('class')0      bird1      bird2    mammal3    mammalName: class, dtype: object
>>> dfname  max_speed0  falcon      389.01  parrot       24.02    lion       80.53  monkey        NaN

请使用df.pop(c)

您可以使用Pandas。

我创建DataFrame:

import pandas as pddf = 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_3Jane        1       2       5Peter       5       4       5Alex        7       7       8Ann         7       6       9

按名称选择一个或多个列:

df[['Test_1', 'Test_3']]
Test_1  Test_3Jane        1       5Peter       5       5Alex        7       8Ann         7       9

您还可以使用:

df.Test_2

你得到列Test_2

Jane     2Peter    4Alex     7Ann      6

您还可以使用#0从这些行中选择列和行。这称为“切片”。请注意,我从第1列到第2列:

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

“切片”是:

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

如果你只是想从Test_1Test_3列中获得PeterAnn

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

你得到:

       Test_1  Test_3Peter       5       5Ann         7       9

我已经看到了几个关于这个问题的答案,但有一个仍然不清楚。你会如何选择那些感兴趣的列?

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

示例

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数组extracted_features,指定63列。原始数据集有103列,我想准确提取这些列,然后我会使用

dataset[extracted_features]

你最终会得到这个

在此输入图片描述

这是您在机器学习中经常使用的东西(更具体地说,在功能选择中)。我也想讨论其他方法,但我认为其他Stack Over的用户已经讨论过了。

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

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

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

df[['a', 'b']]  # Select all rows of 'a' and 'b'columndf.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 5df.iloc[3, 3:5]  # Index 3 of column 3 to 5

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

import pandas as pdimport 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'])

要选择多个列,请在此之后提取并查看它们:df是之前命名的数据帧。然后创建一个新的数据帧df1,并选择要提取和查看的列A到D。

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

所有必需的列将显示!

def get_slize(dataframe, start_row, end_row, start_col, end_col):assert len(dataframe) > end_row and start_row >= 0assert len(dataframe.columns) > end_col and start_col >= 0list_of_indexes = list(dataframe.columns)[start_col:end_col]ans = dataframe.iloc[start_row:end_row][list_of_indexes]return ans

只需使用此功能

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

   A   B    C     D0  1  10  100  10001  2  20  200  2000

选择除两个以外的所有:

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

输出:

   A    C0  1  1001  2  200

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

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

输出:

    B    C0  10  1001  20  200

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

import pandas as pd

cols = ['a', 'b']
df1 = pd.DataFrame(df, columns=cols)
df1 = df.iloc[:, 0:2]