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

时间:2018-12-19 02:26:08

标签: python pandas indexing

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[..,..],有办法实现吗?

4 个答案:

答案 0 :(得分:1)

使用索引,用awk -v q=\' '$0=gensub("(MANAGER\\(" q ")([^" q "]+)(" q "\\))", "\\1PLANET.\\2.STAR\\3", "g")' text 索引第二个元素,使用1,因为python中的索引以1开头:

0

更新:使列转置数据帧,然后获取列print(df['col1'][1]) 0,因为已转置,然后转回:

2

或者:

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

答案 1 :(得分:1)

如上所述,有几种解决方法。需要考虑的两点是:从可读性/ Python风格/习惯用法的角度来看有意义的东西,以及从性能的角度来看有意义的东西。我可能的解决方案不符合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)

APPROACH 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)

该方法可能比前两种方法更易于阅读。

答案 2 :(得分:0)

这能满足您的需求吗? :

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

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

答案 3 :(得分:0)

使用ilocloc

您希望将整数位置索引与基于标签的索引相结合。这通常很麻烦,但是在这里您可以使用以下事实: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']]

由于通常行数超过列数,并且由于整数位置索引自然比基于标签的索引更有效,因此您可能更喜欢ilocloc