如何从 df
中选择列 a
和 b
,并将它们保存到新的数据框 df1
中?
index a b c
1 2 3 4
2 3 4 5
不成功的尝试:
df1 = df['a':'b']
df1 = df.ix[:, 'a':'b']
.ix
,因为它不明确。如果必须,请使用 .iloc
或 .loc
。
> csvtable_imp_1 <- csvtable_imp[0:6]
并选择 0 到 6 之间的第一列的增量量。我所要做的就是读取用 readr lib 分隔的 csv 表。
infile_1 = largefile_stay.ix[:,0:6]
ix
。 Pandas 建议使用:loc
(基于标签的索引)或 iloc
(基于位置的索引)。
无法以您尝试的方式对列名(字符串)进行切片。
在这里,您有几个选择。如果您从上下文中知道要切出哪些变量,则可以通过将列表传递给 __getitem__
syntax([])来仅返回这些列的视图。
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
访问列。
从 0.11.0 版开始,列可以按照您尝试使用 .loc
索引器的方式进行切片:
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).
并返回列 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
...
df.loc[]
似乎比 df[[]]
快。
df.loc[]
更好。
假设您的列名 (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 在 his answer 中指出的那样,df.ix
对列进行更简洁的切片,但 .columns
切片接口可能更自然,因为它使用普通的一维 Python 列表索引/切片语法。
警告:'index'
是 DataFrame
列的错误名称。相同的标签也用于真正的 df.index
属性,即 Index
数组。因此,您的列由 df['index']
返回,而真正的 DataFrame 索引由 df.index
返回。 Index
是一种特殊类型的 Series
,针对其元素值的查找进行了优化。对于 df.index,它用于按标签查找行。该 df.columns
属性也是一个 pd.Index
数组,用于按标签查找列。
.ix
不 仅用于行。用于通用切片,可用于多维切片。它基本上只是 NumPy 常用 __getitem__
语法的一个接口。也就是说,只需应用转置操作 df.T
,您就可以轻松地将列切片问题转换为行切片问题。您的示例使用 columns[1:3]
,这有点误导。 columns
的结果是 Series
;注意不要把它当作一个数组来对待。此外,您可能应该将其更改为 columns[2:3]
以匹配您的“3rd & 4th”评论。
[2:4]
是正确的。您的 [2:3]
错误。并且使用标准 python 切片符号生成序列/系列不会误导 IMO。但我喜欢您绕过 DataFrame 接口以使用 ix
访问底层 numpy 数组。
df.columns
并希望 按标签 对其进行切片,那么您将拥有与 按整数索引位置 对其进行切片的不同切片语义。不过,我在之前的评论中肯定没有很好地解释它。
columns
是一个不可变的系列,并且 getter 已被覆盖以使用标签作为索引。感谢您花时间澄清。
在最新版本的 Pandas 中,有一种简单的方法可以做到这一点。列名(它们是字符串)可以以您喜欢的任何方式进行切片。
columns = ['b', 'c']
df1 = pd.DataFrame(df, columns=columns)
df1 = df.iloc[:, columns]
在您已经拥有数据框时有效。
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
df[['b as foo', 'c as bar']
,输出将列 b
重命名为 foo
,列 c
重命名为 bar
,该怎么办?
df[['b', 'c']].rename(columns = {'b' : 'foo', 'c' : 'bar'})
与熊猫,
机智的列名
dataframe[['column1','column2']]
通过 iloc 和具有索引号的特定列进行选择:
dataframe.iloc[:,[1,2]]
带有 loc 列名可以像这样使用
dataframe.loc[:,['column1','column2']]
您可以使用 pandas.DataFrame.filter
方法过滤或重新排序列,如下所示:
df1 = df.filter(['a', 'b'])
这在链接方法时也非常有用。
filter
很棒,但并没有应有的知名度。特别是,您还可以使用这样的正则表达式:df.filter(regex='a|b')
。我在回答这个问题时有一个更长的例子:stackoverflow.com/questions/29241836/…
您可以使用 Pandas DataFrame 上的 drop()
函数提供要删除的列列表并返回 DataFrame,其中仅包含所需的列。
只是说
colsToDrop = ['a']
df.drop(colsToDrop, axis=1)
将返回仅包含 b
和 c
列的 DataFrame。
drop
方法记录在 here 中。
我发现这个方法非常有用:
# iloc[row slicing, column slicing]
surveys_df.iloc [0:3, 1:4]
更多详细信息,请参见here。
surveys_df.iloc [:, [2,5]]
。
从 0.21.0 开始,不推荐将 .loc
或 []
与一个或多个缺少标签的列表一起使用,而改用 .reindex
。所以,你的问题的答案是:
df1 = df.reindex(columns=['b','c'])
在以前的版本中,只要找到至少一个键,使用 .loc[list-of-labels]
就可以工作(否则会引发 KeyError
)。此行为已弃用,现在显示警告消息。推荐的替代方法是使用 .reindex()
。
在 Indexing and Selecting Data 阅读更多信息。
你可以使用熊猫。
我创建数据框:
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_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
如果您只需要列 Test_1
和 Test_3
中的 Peter
和 Ann
:
df.loc[['Peter', 'Ann'], ['Test_1', 'Test_3']]
你得到:
Test_1 Test_3
Peter 5 5
Ann 7 9
如果你想通过行索引和列名获取一个元素,你可以像 df['b'][0]
那样做。它和你想象的一样简单。
或者您可以使用 df.ix[0,'b']
- 混合使用索引和标签。
注意: 自 v0.20 起,ix
已被弃用,取而代之的是 loc
/ iloc
。
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
df.loc[0:10, 'a':'b']
。我刚刚编辑了它。
尝试使用 pandas.DataFrame.get
(参见 the documentation):
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'])
一种不同且简单的方法:迭代行
使用 itrows
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()
前面的答案中讨论的不同方法是基于这样的假设,即用户知道要删除或子集的列索引,或者用户希望使用一系列列(例如在 '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)
输出将是:
b c
1 3 4
2 4 5
df1 = df[df.columns.difference(columns_for_differencing)]
将返回一个新的/复制的数据帧。您将能够在不更改 df
的情况下修改 df1
。谢谢你,顺便说一句。这正是我所需要的。
您还可以使用 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)
。
我已经看到了几个答案,但我仍然不清楚。您将如何选择那些感兴趣的列?
答案是,如果您将它们收集在一个列表中,您可以使用该列表引用这些列。
例子
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]
你最终会得到这个
https://i.stack.imgur.com/3jLjo.png
这是您在 machine learning 中经常使用的东西(更具体地说,在特征选择中)。我也想讨论其他方式,但我认为其他 Stack Overflower 用户已经涵盖了这一点。
要选择多个列,然后提取并查看它们: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 >= 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
只需使用此功能
我认为这是实现目标的最简单方法。
将熊猫导入为 pd cols = ['a', 'b'] df1 = pd.DataFrame(df, columns=cols) df1 = df.iloc[:, 0:2]
df[['a','b']]
生成一个副本ix[]
,则有关副本的部分仅供参考。ix
接受切片参数,因此您也可以获取列。例如,df.ix[0:2, 0:2]
获取左上角的 2x2 子数组,就像它为 NumPy 矩阵所做的一样(当然取决于您的列名)。您甚至可以对列的字符串名称使用切片语法,例如df.ix[0, 'Col1':'Col5']
。这将获取df.columns
数组中恰好在Col1
和Col5
之间排序的所有列。说ix
索引行是不正确的。这只是它最基本的用途。它还支持比这更多的索引。因此,ix
完全适用于这个问题。.iloc
,它不包括最后一个位置,就像 Python 列表一样。df
,则使用df.iloc[:, [1, 4]]
。通常,如果您想要这种类型的访问模式,您已经知道这些特定的列名,并且您可以使用df.loc[:, ['name2', 'name5']]
,其中'name2'
和'name5'
是您想要的相应列的列字符串名称,或者查看例如name2 = df.columns[1]
的名称。