假设我有一个pandas
Series
对象,并且我想获取其相应值符合某些条件的所有元素(含义索引)。
有很多可能的方法可以实现,但是我希望这是一种简单,有效,惯用的方法-我还没有找到。
This question描述了如何使用布尔索引进行操作,但这对于一个简单的命令来说似乎太冗长了-例如:
import pandas as pd
age = pd.Series(index=['mom','dad','cat1','cat2','baby'],
data=[30,30,3,3,1])
age[age>10].index.values
[编辑:请注意,变量名age
在上一行中出现了两次。当然age[age>10]
很短,但这仅仅是因为age
是一个短名称-如果我遇到带有长名称的系列,例如age_of_family_members_after_filtering
,那么{{1 }}看起来不太好。
我发现的其他解决方案也很冗长:
age_of_family_members_after_filtering[age_of_family_members_after_filtering>10]
或:
age.where(lambda x: x>10).dropna().index.values
(最后一个返回列表,而前一个返回数组,但是我都可以)
由于这是一个非常常见的命令,所以我期望像[name for name, _age in age.items() if _age>10]
之类的东西,而令我惊讶的是找不到它。
我想念什么(如果有的话)? 预先感谢。
答案 0 :(得分:1)
对于给定的解决方案,您可以使用jupyter timeit magic命令进行简单的测试来进行评估:
# %%
%timeit age[age>10].index.values
--> 235 µs ± 8.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# %%
%timeit age.where(lambda x: x>10).dropna().index.values
--> 510 µs ± 14.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# %%
%timeit [name for name, _age in age.items() if _age>10]
--> 12.5 µs ± 429 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
对于给定的解决方案,最后一个是最快的,但是第一个是最简单且仍然完全有效的解决方案。
另一个,请注意效率差异:
age.index[age.values > 10].tolist()
--> 16.5 µs ± 823 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
age.index[age > 10].tolist()
--> 157 µs ± 12.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
更新,带有@Alexander的想法:
# %%
from itertools import compress
%timeit list(compress(age.index, age > 10))
--> 119 µs ± 3.24 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
答案 1 :(得分:1)
您可以压缩索引,但是我不认为它比简单的布尔索引更容易,IMO简洁。
from itertools import compress
>> list(compress(age.index, age > 10))
['mom', 'data']
答案 2 :(得分:1)
大熊猫中的行切片接受可调用对象。因此,您可以
age.loc[lambda x: x > 10]
对于这个小例子来说,看起来有点太多了,但是:
age
而是series_long_after_operation
,这将变得更加清晰age.loc[lambda x: x > 10].loc[lambda x: x%2==0]
第二种方法实际上是进行长管道操作的方法,其中每种方法都返回不同的形状数据框。
答案 3 :(得分:0)
在搜索中,我发现对于一个数据框(尚无等效的序列),可以避免对变量名的重复调用,并且(同样,这可能是可读性问题-取决于编码约定,使用.query
(可能比公认的解决方案性能差很多,但仍然需要注意:
import pandas as pd
df = pd.DataFrame(index=['mom','dad','cat1','cat2','baby'],
data=[30,30,3,3,1],
columns='age')
df.query('age>10')
结果
age
mom 30
dad 30