通过直接索引数据框来选择特定的行和列

问题描述 投票:1回答:4
d = {'col1': [33,34,35], 'col2': [5,6,8], 'col3': [7,8,9]}
df = pd.DataFrame(data=d)
df[['col1','col3']].head()

使用上面的代码,我可以选择col1col3,但是如果我希望只选择第1行和第3行(使用值[33,35][7,9])而不使用任何函数(例如,locilocatiat等。 ) - 纯粹使用数据框索引,例如,df[..,..],有没有办法实现这一目标?

python pandas indexing
4个回答
1
投票

使用索引,1索引第二个元素,使用1,因为python中的索引以0开头:

print(df['col1'][1])

更新获取列转置数据框,然后获取列02,因为转置,然后转置回:

print(df[['col1','col3']].T[[0,2]].T)

要么:

print(df[df.index.isin([0,2])][['col1','col3']])

1
投票

如上所述,有几种方法可以做到这一点。需要考虑的两点是:从可读性/ Pythonic /惯用的角度来看是有意义的,从绩效的角度来看是有意义的。我可能的解决方案不符合OP的完整规范以避免功能,但我会提供它们供考虑和比较。

让我们看看三种方法,并从两个角度考虑它们。

在这种情况下,为了通过计时代码执行来帮助我们更清楚地看到一些性能方面,我们通过重复存储的值100,000次来增加DataFrame的大小。

import pandas as pd
df = pd.DataFrame({'col1':[32, 33, 34] * 100000,
                   'col2':[1, 2, 3] * 100000,
                   'col3':[1, 2, 3] * 100000,
                  })

方法1

此方法使用@ U9-Forward概述的过程,即按列索引,转置行和列,以便您可以索引所需的行并将DataFrame转换回原始方向。

在Jupyter中使用%timeit,我们看到这种方法需要多长时间来处理:

[1]: %timeit df[['col1', 'col3']].T[[0, 2]].T
     3.02 ms ± 16.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

方法2

此方法基于所需行和索引的列表创建掩码,并基于该掩码过滤DataFrame,然后仅选择所需的列。这与@ jpp的方法有一些相似之处,但不使用.loc

同样,使用%timeit ......我们看到这种方法只需要方法1的一半。

[2]: %timeit df[df.index.isin([0, 2])][['col1', 'col3']]
     1.61 ms ± 31.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

方法3

第三种方法使用.take()方法从DataFrame中选择特定行,然后为所需列索引。

再次,使用%timeit,我们发现这种方法比方法2快三倍,比方法1快六倍。

[1]: %timeit df.take([0, 2])[['col1','col3']]
     507 µs ± 5.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

也有争议的是,这种方法比前两种方法更容易阅读。


0
投票

这会满足您的需求吗? :

df[['col1','col3']][::2]

在这里,我利用了您询问的行索引(0和2)可以表示为切片的事实。但是,对于任意一组行索引,可能无法使其变得简单


0
投票

Use iloc or loc

您希望将整数位置索引与基于标签的索引相结合。这通常很麻烦,但在这里你可以使用iloc支持整数位置和布尔数组索引的事实:

d = {'col1': [33,34,35], 'col2': [5,6,8], 'col3': [7,8,9]}
df = pd.DataFrame(data=d)

res = df.iloc[[0, 2], df.columns.isin(['col1', 'col3'])]

print(res)

   col1  col3
0    33     7
2    35     9

Python中的索引以0开头,因此第一行和第三行由[0, 2]表示。

另一种方法是使用loc和行的布尔索引:

res = df.loc[df.index.isin([0, 2]), ['col1', 'col3']]

由于通常行数超过列数,并且因为整数位置索引自然比基于标签更有效,所以您可能更喜欢iloc而不是loc

© www.soinside.com 2019 - 2024. All rights reserved.