day81-数据规整:聚合、合并和重塑及数据结构
1层次化索引
在许多应用中,数据可能分散在许多文件或数据库中,存储的形式也不利于分析,应采用聚合、合并、重塑数据的方法进行处理。
层次化索引(hierarchical indexing)是pandas的一项重要功能,它使你能在一个轴上拥有多 个(两个以上)索引级别。stack()是unstack()的逆运算;stack()能将单轴上两个索引的表进行横纵转换
data = pd.Series(np.random.randn(9), index=[['a', 'a', 'a', 'b',
'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]])
data['b':'c']
data.loc[:, 2] # 从内层中选取
data.unstack() # 将内层索引转化为列的索引,(横纵表转换)
data.unstack().stack() # stack()是unstack()的逆运算
对于一个DataFrame,每条轴都可以有分层索引
frame = pd.DataFrame(np.arange(12).reshape((4, 3)), index=[['a', 'a', 'b', 'b'],
[1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']])
frame.index.names = ['key1', 'key2'] # 给index的内外层命名
frame.columns.names = ['state', 'color'] # 给columns的内外层命名
frame['Ohio']
给内外层命了名后,可以利用内外层索引的名字进行选取列分组
2重排与分级排序
重排与分级排序即是调整某条轴上的各级别的顺序
frame.swaplevel('key1', 'key2') # 交换key1,key2的顺序
而sort_index则根据单个级别中的值对数据进行排序。交换级别时,常也会用到 sort_index,这样最终结果就是按照指定顺序进行字母排序了;
frame.sort_index(level=1) # 对index索引进行排序,按内层排序
frame.swaplevel(0, 1).sort_index(level=0) # 交换内外层的index索引并按外层排序
frame.sort_index(level=1) # 对index索引进行排序,按内层排序
frame.swaplevel(0, 1).sort_index(level=0) # 交换内外层的index索引并按外层排序
根据级别汇总统计
对DataFrame和Series的描述和汇总统计都有一个level选项,它用于指定在某条轴上求和的级 别。
frame.sum(level='key2')
frame.sum(level='color', axis=1)
使用DataFrame的列进行索引
将DataFrame的一个或多个列当做行索引来用,或者可能希望将行索引变成DataFrame的列
frame = pd.DataFrame({'a': range(7), 'b': range(7, 0, -1), 'c': ['one', 'one',
'one', 'two', 'two', 'two', 'two'], 'd': [0, 1, 2, 0, 1, 2, 3]})
frame2 = frame.set_index(['c', 'd'])
frame.set_index(['c', 'd'], drop=False)
frame2.reset_index()
reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里面
3合并数据集
pandas对象中的数据可以通过一些方式进行合并
pandas.merge可根据一个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库的用户对此应该会比较熟悉,因为它实现的就是数据库的join操作。
pandas.concat可以沿着一条轴将多个对象堆叠到一起。
实例方法combine_first可以将重复数据拼接在一起,用一个对象中的值填充另一个对象中的缺失值
数据库风格的DataFrame合并
数据集的合并(merge)或连接(join)运算是通过一个或多个键将行连接起来的
df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})
df2 = pd.DataFrame({'key': ['a', 'b', 'd'], 'data2': range(3)})
pd.merge(df1, df2) # 合并df1,df2(多对一合并)
没有指明要用哪个列进行连接。如果没有指定,merge就会将重叠列的列名当做键。最好明确指定一下
pd.merge(df1, df2, on='key')
如果两个对象的列名不同,也可以分别进行指定
df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})
df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'], 'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey')
结果里面c和d以及与之相关的数据消失了了。默认情况下,merge做的是“内连接”;结果中的键 是交集。其他方式还有”left”、”right”以及”outer”。外连接求取的是键的并集,组合了左连接 和右连接的效果
pd.merge(df1, df2, how='outer') # 外连接
连接说明:inner,使用两个表都有的键进行连接;left:使用左表中所有的键进行连接;right:使用右表中所有的键进行连接;outer:使用两个表中所有的键进行连接。
多对多的合并:
df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6)})
df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'], 'data2': range(5)})
pd.merge(df1, df2, on='key', how='left')
多对多连接,由于左边的DataFrame有3个”b”行,右边的有2个,所以最终结果中就有6 个”b”行
pd.merge(df1, df2, how='inner')
根据多个键进行合并
left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'], 'key2': ['one', 'two', 'one'],
'lval': [1, 2, 3]})
right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'], 'key2': ['one',
'one', 'one', 'two'], 'rval': [4, 5, 6, 7]})
pd.merge(left, right, on=['key1', 'key2'], how='outer')
重复列名的处理
pd.merge(left, right, on='key1')
pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
4数据结构(data structure)
堆栈 Stack - 先进后出(FILO),后进先出
放数据到栈的过程中叫压栈 PUSH, 取数据的过程叫弹栈 POP;MAXSIZE最长节数
队列 QUEUE - 先进先出(FIFO)
放数据到队列的过程 PUSH, 取数据的过程 POP;MAXSIZE最长节数
线性表/顺序表 List SequenceList 不适宜做增加删除,元素可通过索引直接定位,速度快
maxsize = 5 连续存放,可以用索引直接定位元素
链表 LinkedList 适合做增加删除数据,定位元素慢(通过head往后面查找)
链表由一个个的D(data)|N(next)组成,N指向D,一个D|N叫一个Node节点
head → D|N - Node节点 → D|N → D|N
二叉树
root→ L(左指针) D(数据) R(右指针) - 每一个左指针和右指针又可以指向一个ldr的节点,一直指下去
二叉树由根及中间节点及最末端节点(叶子)组成