逐列选择pandas数据帧

csa*_*der 11 dataframe python-3.x pandas

在我的一个脚本中,我通过列名列表选择数据框的几列.以下代码有效:

data = df[lst]
Run Code Online (Sandbox Code Playgroud)

只要列表中的所有元素都包含在数据框中,它就可以正常工作.如果不是这样,它将返回错误"'....'不在索引中".

是否有可能仍然选择列名包含在该列表中的所有列,即使列表中的所有元素都不包含在数据框中?

jez*_*ael 29

我想你需要Index.intersection:

df = pd.DataFrame({'A':[1,2,3],
                   'B':[4,5,6],
                   'C':[7,8,9],
                   'D':[1,3,5],
                   'E':[5,3,6],
                   'F':[7,4,3]})

print (df)
   A  B  C  D  E  F
0  1  4  7  1  5  7
1  2  5  8  3  3  4
2  3  6  9  5  6  3

lst = ['A','R','B']

print (df.columns.intersection(lst))
Index(['A', 'B'], dtype='object')

data = df[df.columns.intersection(lst)]
print (data)
   A  B
0  1  4
1  2  5
2  3  6
Run Code Online (Sandbox Code Playgroud)

另一个解决方案numpy.intersect1d:

data = df[np.intersect1d(df.columns, lst)]
print (data)
   A  B
0  1  4
1  2  5
2  3  6
Run Code Online (Sandbox Code Playgroud)


Zer*_*ero 19

其他方法很少,列表理解要快得多

In [1357]: df[df.columns & lst]
Out[1357]:
   A  B
0  1  4
1  2  5
2  3  6

In [1358]: df[[c for c in df.columns if c in lst]]
Out[1358]:
   A  B
0  1  4
1  2  5
2  3  6
Run Code Online (Sandbox Code Playgroud)

时间安排

In [1360]: %timeit [c for c in df.columns if c in lst]
100000 loops, best of 3: 2.54 µs per loop

In [1359]: %timeit df.columns & lst
1000 loops, best of 3: 231 µs per loop

In [1362]: %timeit df.columns.intersection(lst)
1000 loops, best of 3: 236 µs per loop

In [1363]: %timeit np.intersect1d(df.columns, lst)
10000 loops, best of 3: 26.6 µs per loop
Run Code Online (Sandbox Code Playgroud)

细节

In [1365]: df
Out[1365]:
   A  B  C  D  E  F
0  1  4  7  1  5  7
1  2  5  8  3  3  4
2  3  6  9  5  6  3

In [1366]: lst
Out[1366]: ['A', 'R', 'B']
Run Code Online (Sandbox Code Playgroud)


Joh*_*hnE 14

这里一个非常简单的解决方案是使用filter(). 在您的示例中,只需键入:

df.filter(lst)
Run Code Online (Sandbox Code Playgroud)

它会自动忽略任何缺失的列。有关更多信息,请参阅filter 的文档

一般而言,filter这是一种非常灵活且强大的选择特定列的方法。特别是,您可以使用正则表达式。借用 @jezrael 的示例数据,您可以键入以下任一内容。

df.filter(regex='A|R|B')
df.filter(regex='[ARB]')
Run Code Online (Sandbox Code Playgroud)

这些都是简单的示例,但假设您只需要以这些字母开头的列,那么您可以输入:

df.filter(regex='^[ARB]')
Run Code Online (Sandbox Code Playgroud)

FWIW,在一些快速计时中,我发现这比列表理解方法更快,但我不认为速度在这里真正是一个问题——即使是最慢的方法也应该足够快,因为速度不依赖于数据框的大小,仅取决于列数。

老实说,所有这些方法都很好,您可以选择对您来说最易读的方法。我更喜欢过滤器,因为它很简单,同时还为您提供了比简单交集更多的选择列的选项。


Avi*_*ash 9

*与列表一起使用

data = df[[*lst]]

它将给出所需的结果。