Pandas中兼并数组和字典功能的Series 2013-03-24 11:24:00 分类: Python/Ruby In [2]: # 这段代码用于并排显示多个Series对象 from it
分類: Python/Ruby
In?[2]: # 這段代碼用于并排顯示多個Series對象 from itertools import izip_longest def C(*args, **kw): ????gap = kw.pop("gap", 5) ????results = [] ???? ????for item in args: ????????if isinstance(item, tuple): ????????????results.append("\n".join(unicode(row) for row in item).split("\n")) ???????????? ????for i, item in enumerate(results): ????????width = max(len(row.encode("gb2312")) for row in item) ????????results[i].insert(1, "-"*width)???????? ????????results[i] = [row.encode("gb2312").ljust(width+gap).decode("gb2312") for row in item] ????for row in izip_longest(*results, fillvalue=""): ????????print "".join(row)兼并數組和字典功能的Series
In?[3]: import pandas as pdSeries對象本質上是一個NumPy的數組,因此NumPy的數組處理函數可以直接對Series進行處理。但是Series除了可以使用位置作為下標存取元素之外,還可以使用標簽下標存取元素,這一點和字典相似。每個Series對象實際上都由兩個數組組成:
- index: 它是從NumPy數組繼承的Index對象,保存標簽信息。
- values: 保存值的NumPy數組。
下面創建一個Series對象,并查看其兩個屬性:
In?[4]: s = pd.Series([1,2,3,4,5], index=["a","b","c","d","e"]) print s.index print s.values Index([a, b, c, d, e], dtype=object) [1 2 3 4 5]Series的下標存取,同時支持位置和標簽兩種形式:
In?[5]: print s[2], s["d"] 3 4Series也支持位置切片和標簽切片。位置切片遵循Python的切片規則,包括起始位置,但不包括結束位置;但標簽切片則同時包括起始標簽和結束標簽。之所以如此設計是因為在使用標簽切片時,通常我們不知道標簽的順序,如果不包含結束標簽,很難確定結束標簽的前一個標簽是什么。
In?[6]: C((u"s[1:3]", s[1:3]), (u"s['b':'d']", s['b':'d'])) s[1:3]???? s['b':'d']???? ------???? ----------???? b????2???? b????2???????? c????3???? c????3???????? d????4????????和NumPy數組一樣,Series也可以使用一個位置列表或者位置數組進行存取;同時還可以使用標簽列表和標簽數組。
In?[7]: C((u"s[[1,3,2]]", s[[1,3,2]]), (u"s[['b','d','c']]", s[['b','d','c']])) s[[1,3,2]]???? s[['b','d','c']]???? ----------???? ----------------???? b????2???????? b????2???????????? d????4???????? d????4???????????? c????3???????? c????3????????????可以看出Series同時具有數組和字典的功能,因此它也支持一些字典的方法,例如Series.iteritems():
In?[8]: print list(s.iteritems()) [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]Series魔法都在Index里
Index對象也是ndarray的派生類,values屬性可以獲得ndarray數組:
In?[31]: index = s.index print index.__class__.mro() index.values [, , ] Out[31]: array(['a', 'b', 'c', 'd', 'e'], dtype=object)Index可以當作一維數組,支持所有的數組下標操作:
In?[35]: print index[[1, 3]] print index[index > 'c'] print index[1::2] Index([b, d], dtype=object) Index([d, e], dtype=object) Index([b, d], dtype=object)Index也具有字典的映射功能,它將數組中的值映射到其位置:
- Index.get_loc(value): 獲得單個值value的下標
- Index.get_indexer(values): 獲得一組值values的下標,當值不存在時,得到-1
Index的魔法在Engine里
Index對象的字典功能由其中的Engine對象提供:
In?[18]: e = s.index._engine print e In?[22]: e.get_loc('b') Out[22]: 1 In?[42]: e.get_indexer(np.array(['a', 'd', 'e', 'z'], 'O')) Out[42]: array([ 0, 3, 4, -1])Engine中的HashTable
Engine對象的字典功能由mapping提供:
In?[19]: ht = e.mapping print ht In?[53]: ht.get_item('d') Out[53]: 3 In?[55]: ht.lookup(np.array(['a', 'd', 'e', 'z'], 'O')) Out[55]: array([ 0, 3, 4, -1])值不唯一的Index
當Index中的每個值都唯一時,可以使用HashTable將值映射到其位置之上。若值不唯一,則Pandas會采用兩種較慢的算法。
- 值唯一時,采用HashTable映射,復雜度為O(1),但需要額外的內存保存HashTable
- 值排序時使用二分搜索法,復雜度為O(log2(N))
- 值無序時則逐個比較,復雜度為O(N)
在Pandas的內部實現中,還考慮了內存的因素,因此對于較大的、排序的、值唯一的Index,也會采用二分搜索法,省去了由HashTable帶來的額外內存開銷。
下面我們創建這三種Index對象:
In?[80]: N = 10000 unique_keys = np.array(list(set(pd.core.common.rands(5) for i in xrange(N))), 'O') duplicate_keys = unique_keys.copy() duplicate_keys[-1] = duplicate_keys[0] sorted_keys = np.sort(duplicate_keys) unique_index = pd.Index(unique_keys) sorted_index = pd.Index(sorted_keys) duplicate_index = pd.Index(duplicate_keys) to_search = unique_keys[N-2]每個Index都有is_unique和is_monotonic屬性,分別表示值是否唯一,和是否排序。下面的程序顯示上面三個Index對象的屬性:
In?[101]: from itertools import product def dataframe_fromfunc(func, index, columns): ????return pd.DataFrame([[func(idx, col) for col in columns] for idx in index], ????????????index = index, columns = columns) predicates = ["is_unique", "is_monotonic"] index = ["unique_index", "sorted_index", "duplicate_index"] dataframe_fromfunc(lambda idx, pred:getattr(globals()[idx], pred), index, predicates) Out[101]:| True | False |
| False | True |
| False | False |
所有的Index都支持get_loc(),但只有值唯一的Index才支持get_indexer()。三者的get_loc()方法所返回的位置信息也不同:
- unique_index:由于值是唯一的,因此返回一個整數
- sorted_index:由于值是排序的,因此返回一個slice對象
- duplicate_index:返回一個布爾數組
這三種返回值都可以作為下標存取ndarray中的值。
In?[103]: print unique_index.get_loc(unique_keys[0]) print sorted_index.get_loc(unique_keys[0]) print duplicate_index.get_loc(unique_keys[0]) 0 slice(8528, 8530, None) [ True False False ..., False False True]下面比較三者的運算速度:
In?[81]: %timeit unique_index.get_loc(to_search) 1000000 loops, best of 3: 828 ns per loop In?[82]: %timeit sorted_index.get_loc(to_search) 100000 loops, best of 3: 15.2 us per loop In?[83]: %timeit duplicate_index.get_loc(to_search) 1000 loops, best of 3: 284 us per loop總結
以上是生活随笔為你收集整理的Pandas中兼并数组和字典功能的Series 2013-03-24 11:24:00 分类: Python/Ruby In [2]: # 这段代码用于并排显示多个Series对象 from it的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python基础学习-Python中最常
- 下一篇: 信用风险模型(申请评分、行为评分)与数据