我知道这是一个非常基本的问题,但由于某些原因我无法找到答案。如何在python pandas中获取Series的某个元素的索引? (第一次出现就足够了)
是的,我想要像:import pandas as pd
myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
print myseries.find(7) # should output 3
当然,可以用循环来定义这样的方法:
def find(s, el):
for i in s.index:
if s[i] == el:
return i
return None
print find(myseries, 7)
但我认为应该有更好的方法。有吗?
答案 0 :(得分:140)
>>> myseries[myseries == 7]
3 7
dtype: int64
>>> myseries[myseries == 7].index[0]
3
虽然我承认应该有更好的方法,但这至少可以避免迭代和循环遍历对象并将其移动到C级。
答案 1 :(得分:30)
转换为索引,您可以使用get_loc
In [1]: myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
In [3]: Index(myseries).get_loc(7)
Out[3]: 3
In [4]: Index(myseries).get_loc(10)
KeyError: 10
重复处理
In [5]: Index([1,1,2,2,3,4]).get_loc(2)
Out[5]: slice(2, 4, None)
如果非连续返回
,将返回一个布尔数组In [6]: Index([1,1,2,1,3,2,4]).get_loc(2)
Out[6]: array([False, False, True, False, False, True, False], dtype=bool)
在内部使用哈希表,快速
In [7]: s = Series(randint(0,10,10000))
In [9]: %timeit s[s == 5]
1000 loops, best of 3: 203 µs per loop
In [12]: i = Index(s)
In [13]: %timeit i.get_loc(5)
1000 loops, best of 3: 226 µs per loop
正如Viktor所指出的那样,创建索引会产生一次性的创建开销(当你真正对索引做某事时会产生这种开销,例如is_unique
)
In [2]: s = Series(randint(0,10,10000))
In [3]: %timeit Index(s)
100000 loops, best of 3: 9.6 µs per loop
In [4]: %timeit Index(s).is_unique
10000 loops, best of 3: 140 µs per loop
答案 2 :(得分:9)
In [92]: (myseries==7).argmax()
Out[92]: 3
如果您事先知道7,那么这是有效的。你可以用它来检查 (myseries == 7).any()
另一种方法(非常类似于第一个答案)也考虑了多个7(或没有)
In [122]: myseries = pd.Series([1,7,0,7,5], index=['a','b','c','d','e'])
In [123]: list(myseries[myseries==7].index)
Out[123]: ['b', 'd']
答案 3 :(得分:3)
另一种方法,虽然同样不满意,但是:
s = pd.Series([1,3,0,7,5],index=[0,1,2,3,4])
list(s).index(7)
返回: 3
使用我正在使用的当前数据集的时间测试(考虑它是随机的):
[64]: %timeit pd.Index(article_reference_df.asset_id).get_loc('100000003003614')
10000 loops, best of 3: 60.1 µs per loop
In [66]: %timeit article_reference_df.asset_id[article_reference_df.asset_id == '100000003003614'].index[0]
1000 loops, best of 3: 255 µs per loop
In [65]: %timeit list(article_reference_df.asset_id).index('100000003003614')
100000 loops, best of 3: 14.5 µs per loop
答案 4 :(得分:2)
如果你使用numpy,你可以得到一个你的值找到的一系列凹痕:
import numpy as np
import pandas as pd
myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
np.where(myseries == 7)
这将返回一个元素元组,其中包含一个indecies数组,其中7是myseries中的值:
(array([3], dtype=int64),)
答案 5 :(得分:1)
您可以使用Series.idxmax()
>>> import pandas as pd
>>> myseries = pd.Series([1,4,0,7,5], index=[0,1,2,3,4])
>>> myseries.idxmax()
3
>>>
答案 6 :(得分:0)
参考Viktor Kerkez(8月20日&13; 13:5:52)Jonathan Eunice(11月7日和16日13:03)
>>> myseries[myseries == 7]
3 7
dtype: int64
>>> myseries[myseries == 7].index # using index[0] specifies the output of the first occurrence only. Using index without adding the element index will give you indexes all occurrences if the series had more then one 7 there. It still presumes you know which number you are looking for.
3
答案 7 :(得分:0)
通常,您的价值出现在多个指标上:
>>> myseries = pd.Series([0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
>>> myseries.index[myseries == 1]
Int64Index([3, 4, 5, 6, 10, 11], dtype='int64')
答案 8 :(得分:0)
我对这里的所有答案印象深刻。这不是一个新的答案,只是尝试总结所有这些方法的时间。我考虑了一个由25个元素组成的系列的情况,并假设一般情况下索引可以包含任何值,并且您希望索引值与该系列末尾的搜索值相对应。
以下是使用python 3.7的2013 MacBook Pro的速度测试。
In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: data = [406400, 203200, 101600, 76100, 50800, 25400, 19050, 12700,
...: 9500, 6700, 4750, 3350, 2360, 1700, 1180, 850,
...: 600, 425, 300, 212, 150, 106, 75, 53,
...: 38]
In [4]: myseries = pd.Series(data, index=range(1,26))
In [5]: myseries[21]
Out[5]: 150
In [7]: %timeit myseries[myseries == 150].index[0]
416 µs ± 5.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [8]: %timeit myseries[myseries == 150].first_valid_index()
585 µs ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [9]: %timeit myseries.where(myseries == 150).first_valid_index()
652 µs ± 23.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [10]: %timeit myseries.index[np.where(myseries == 150)[0][0]]
195 µs ± 1.18 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [11]: %timeit myseries.index[pd.Index(myseries).get_loc(150)]
77.4 µs ± 1.41 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [12]: %timeit myseries.index[list(myseries).index(150)]
14.1 µs ± 42.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
@杰夫的答案似乎是最快的-尽管它不能处理重复项。
更正 :抱歉,我错过了一个,@ Alex Spangher使用列表索引方法的解决方案是最快的。
希望这会有所帮助。
如此简单的操作需要如此复杂的解决方案,而许多解决方案是如此之慢,真令人惊讶。在某些情况下,超过半毫秒才能找到一系列25的值。
答案 9 :(得分:0)
尚未提及的另一种方法是tolist方法:
myseries.tolist().index(7)
应该假设序列中存在该值,则应返回正确的索引。
答案 10 :(得分:0)
这是我能找到的最原生和可扩展的方法:
>>> myindex = pd.Series(myseries.index, index=myseries)
>>> myindex[7]
3
>>> myindex[[7, 5, 7]]
7 3
5 4
7 3
dtype: int64
答案 11 :(得分:0)
Pandas 具有内置类 Index
,带有一个名为 get_loc
的函数。这个函数要么返回
index(元素索引)
切片(如果指定的数字是有序的)
数组(如果数字位于多个索引处,则为布尔数组)
示例:
import pandas as pd
>>> mySer = pd.Series([1, 3, 8, 10, 13])
>>> pd.Index(mySer).get_loc(10) # Returns index
3 # Index of 10 in series
>>> mySer = pd.Series([1, 3, 8, 10, 10, 10, 13])
>>> pd.Index(mySer).get_loc(10) # Returns slice
slice(3, 6, None) # 10 occurs at index 3 (included) to 6 (not included)
# If the data is not in sequence then it would return an array of bool's.
>>> mySer = pd.Series([1, 10, 3, 8, 10, 10, 10, 13, 10])
>>> pd.Index(mySer).get_loc(10)
array([False, True, False, False, True, True, False, True])
还有很多其他选择,但我觉得这对我来说非常简单。