有这样的系列:
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
并且它完成了这项工作,但不知何故,索引会像列一样喊出“包含”...
有更好的方法吗?
答案 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)
如何通过索引上的部分字符串匹配选择行?
我们现在为这些操作提供了“向量化”字符串方法(实际上,它们已经存在了一段时间)。所有解决方案都可以按原样适用于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
相同的解决方案将同时应用于s
和df
!
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?上的大量文章。