通过索引中的部分字符串匹配来选择行

时间:2013-05-17 20:30:32

标签: python pandas

有这样的系列:

ds = Series({'wikipedia':10,'wikimedia':22,'wikitravel':33,'google':40})

google        40
wikimedia     22
wikipedia     10
wikitravel    33
dtype: int64

我想选择'wiki'是索引标签一部分的行(部分字符串标签)。

目前我试过

ds[ds.index.map(lambda x: 'wiki' in x)]

wikimedia     22
wikipedia     10
wikitravel    33
Name: site, dtype: int64

并且它完成了这项工作,但不知何故,索引会像列一样喊出“包含”...

有更好的方法吗?

3 个答案:

答案 0 :(得分:11)

有点厚颜无耻的方式可能是使用loc

In [11]: ds.loc['wiki': 'wikj']
Out[11]:
wikimedia     22
wikipedia     10
wikitravel    33
dtype: int64

这基本上等同于ds[ds.index.map(lambda s: s.startswith('wiki'))]

要做包含,正如@DSM建议的那样,写作可能更好:

ds[['wiki' in s for s in ds.index]]

答案 1 :(得分:5)

使用filter的另一种解决方案,请参阅here

>>> ds.filter(like='wiki', axis=0)
wikimedia     22
wikipedia     10
wikitravel    33
dtype: int64

答案 2 :(得分:3)

  

如何通过索引上的部分字符串匹配选择行?

更新时间:2019年

我们现在为这些操作提供了“向量化”字符串方法(实际上,它们已经存在了一段时间)。所有解决方案都可以按原样适用于DataFrames。

设置

s = pd.Series({'foo': 'x', 'foobar': 'y', 'baz': 'z'})
s

foo       x
foobar    y
baz       z
dtype: object

df = s.to_frame('abc')
df

       abc
foo      x
foobar   y
baz      z

相同的解决方案将同时应用于sdf


搜索前缀: str.startswith

str dtype(更准确地说是object dtype)pd.Index对象现在带有str方法本身,因此您可以使用Series.str.startswith来惯用地指定它,

# For the series, 
s.index.str.startswith('foo')         
# Similarly, for the DataFrame,
df.index.str.startswith('foo')

# array([ True,  True, False])

要选择此结果,可以使用布尔索引,

s[s.index.str.startswith('foo') ]

foo       x
foobar    y
dtype: object

df[df.index.str.startswith('foo')]

       abc
foo      x
foobar   y

在任何地方搜索:str.contains

使用Series.str.contains在字符串中的任何位置执行基于子字符串或基于正则表达式的搜索:

s.index.str.contains('foo')
# Similarly,
df.index.str.contains('foo')

# array([ True,  True, False])

如果只是匹配子字符串,则可以安全地禁用基于正则表达式的搜索以提高性能:s.index.str.contains('foo', regex=False)

对于正则表达式,您可以使用

s.index.str.contains('ba')
# Similarly,
df.index.str.contains('ba')

# array([False,  True,  True])

通过列表理解进行微观优化

从性能的角度来看,列表理解刚好更快。第一个选项可以用

重写
[x.startswith('foo') for x in s.index]
# [True, True, False]

s[[x.startswith('foo') for x in s.index]]

foo       x
foobar    y
dtype: object

使用正则表达式,您可以预编译模式并调用re.search。有关更多信息,请参见我在For loops with pandas - When should I care?上的大量文章。