我有一个看起来像这样的系列:
s = pd.Series(['abdhd','abadh','aba', 'djjb','kjsdhf','abwer', 'djd, 'kja'])
我需要选择字符串以' dh'开头的所有行。或者' kj'
我试图使用.startswith()和.match();但我得到布尔返回True和False而不是列表的值。
我也尝试将其作为词典的一部分,并获得了相同的bool回报,而不是自己的价值。
我还能做些什么吗?
答案 0 :(得分:3)
尝试
s[(s.str.startswith('dh')) | (s.str.startswith('kj'))]
说明:(s.str.startswith('dh')) | (s.str.startswith('kj'))
是您关心的逻辑条件,然后将其放在s[]
内部按行切片,只返回条件为True
的行
答案 1 :(得分:2)
pd.Series.str.contains
s[s.str.contains('^dh|kj')]
4 kjsdhf
7 kja
dtype: object
pd.Series.isin
s[s.str[:2].isin(['dh', 'kj'])]
4 kjsdhf
7 kja
dtype: object
理解str.startswith
s[[any(map(x.startswith, ['dh', 'kj'])) for x in s]]
4 kjsdhf
7 kja
dtype: object
pir1 = lambda s: s[s.str.contains('^dh|kj')]
pir2 = lambda s: s[s.str[:2].isin(['dh', 'kj'])]
pir3 = lambda s: s[[any(map(x.startswith, ['dh', 'kj'])) for x in s]]
alol = lambda s: s[(s.str.startswith('dh')) | (s.str.startswith('kj'))]
测试
res = pd.DataFrame(
np.nan, [10, 30, 100, 300, 1000, 3000, 10000, 30000],
'pir1 pir2 pir3 alol'.split()
)
for i in res.index:
s_ = pd.concat([s] * i)
for j in res.columns:
stmt = f'{j}(s_)'
setp = f'from __main__ import {j}, s_'
res.at[i, j] = timeit(stmt, setp, number=200)
结果
res.plot(loglog=True)
res.div(res.min(1), 0)
pir1 pir2 pir3 alol
10 2.424637 3.272403 1.000000 4.747473
30 2.756702 2.812140 1.000000 4.446757
100 2.673724 2.190306 1.000000 3.128486
300 1.787894 1.000000 1.342434 1.997433
1000 2.164429 1.000000 1.788028 2.244033
3000 2.325746 1.000000 1.922993 2.227902
10000 2.424354 1.000000 2.042643 2.242508
30000 2.153505 1.000000 1.847457 1.935085
结论
唯一真正的赢家(并且只是勉强)是isin
,它也恰好是最不普遍的。只要你只看前两个字符,你就可以真正扩展它的用途。
除此之外,其他方法似乎都具有相似的时间复杂度。