快乐学习
前程无忧、中华英才非你莫属!

原创-Pandas心法之分层索引-4

"""
# 7、分层索引、
"""

import pandas as pd
import numpy as np

index = [('California', 2000), ('California', 2010),
         ('New York', 2000), ('New York', 2010),
         ('Texas', 2000), ('Texas', 2010)]
populations = [33871648, 37253956,
               18976457, 19378102,
               20851820, 25145561]

pop = pd.Series(populations, index=index)
print(pop)

# 切片
print(pop[('California', 2010):('Texas', 2000)])

# 例如,如果您需要从2010年中选择所有值
# 通过列表生成式,来生成2010对应的索引数据
print(pop[[i for i in pop.index if i[1] == 2010]])

# 上面的列表生成式的索引方式,代码看起来还是有些小复杂
# 下面我们用MultiIndex分层索引
'''
请注意,其中MultiIndex包含多个索引级别-在这种情况下,包括状态名称和年份,以及为每个数据点编码这些级别的多个标签。
'''
index = pd.MultiIndex.from_tuples(index)
print(index)

# 重置索引
pop = pop.reindex(index)
print(pop)

# 再次查询2010年的所有数据
print(pop[:, 2010])

# 取消堆叠
pop_df = pop.unstack()
print(pop_df)

# 堆叠
print(pop_df.stack())

# 添加一列
pop_df = pd.DataFrame({'total': pop,
                       'under18': [9267089, 9284094,
                                   4687374, 4318033,
                                   5906301, 6879014]})

print(pop_df)

# 根据上述数据,我们在此按年份计算了18岁以下的人口比例
f_u18 = pop_df['under18'] / pop_df['total']
print(f_u18.unstack())

# 创建多个索引的df
df = pd.DataFrame(np.random.rand(4, 2),
                  index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]],
                  columns=['data1', 'data2'])

print(df)

data = {('California', 2000): 33871648,
        ('California', 2010): 37253956,
        ('Texas', 2000): 20851820,
        ('Texas', 2010): 25145561,
        ('New York', 2000): 18976457,
        ('New York', 2010): 19378102}

print(pd.Series(data))

# 通过多个一维数组创建多维索引
index1 = pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'], [1, 2, 1, 2]])
print(index1)

# 通过多个元组创建多维索引
index2 = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)])
print(index2)

# 通过单个索引的笛卡尔积构造它
index3 = pd.MultiIndex.from_product([['a', 'b'], [1, 2]])
print(index3)

# 通过传递levels(包含每个级别的可用索引值labels的列表的列表)和(引用这些标签的列表的列表)直接使用其内部编码来构造:
index4 = pd.MultiIndex(levels=[['a', 'b'], [1, 2]],
                       codes=[[0, 0, 1, 1], [0, 1, 0, 1]])
print(index4)

print(pop.index)

# 给多层索引的Series 索引起名
pop.index.names = ['state', 'year']
print(pop)

# 层次索引和列
index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]], names=['year', 'visit'])

columns = pd.MultiIndex.from_product([['Bob', 'Guido', 'Sue'], ['HR', 'Temp']], names=['subject', 'type'])

# mock 一些数据
data = np.round(np.random.randn(4, 6), 1)
data[:, ::2] *= 10
data += 37

# create the DataFrame
health_data = pd.DataFrame(data, index=index, columns=columns)

'''DataFrames乘法索引'''
print(health_data)

# 通过人名来访问
print(health_data['Guido'])

# 索引和切片一个多指标
print(pop)

# 通过部分索引取值
print(pop['California'])

# 通过完整索引取值
print(pop['California', 2000])

# 通过部分索引,切片取值
print(pop.loc['California':'New York'])

# 使用部分索引取值.
print(pop.loc[:, 2000])

# 使用布尔索引
print(pop[pop > 22000000])

# 使用花式索引
print(pop[['California', 'Texas']])
print(health_data)
print(health_data['Guido', 'HR'])
print(health_data.iloc[:2, :2])  # 2行,2列
print(health_data.loc[:, ('Bob', 'HR')])

# 元组中创建切片将导致语法错误:
# print(health_data.loc[(:,1), (:, 'HR')])

# 上述解决方案
idx = pd.IndexSlice
print(health_data.loc[idx[:, 1], idx[:, 'HR']])

'''
警告 如果索引未排序,许多MultiIndex切片操作将失败。
'''

index = pd.MultiIndex.from_product([['a', 'c', 'b'], [1, 2]])
data = pd.Series(np.random.rand(6), index=index)
data.index.names = ['char', 'int']
print(data)

# 出错的原因就是,未对MultiIndex进行排序的结果。
# 熊猫提供了许多方便的例程来执行这种排序
# sort_index()和sortlevel()方法
try:
    data['a':'b']
except KeyError as e:
    print(type(e))
    print(e)

data = data.sort_index()
print(data)

print(data['a':'b'])

'''
Stacking and unstacking indices¶

说明:
如前所述,可以将数据集从堆叠的多索引转换为简单的二维表示形式,可以选择指定要使用的级别:
'''
print(pop)
print('---------------------')

print(pop.unstack(level=0))

print('---------------------')

print(pop.unstack(level=1))

print('---------------------')
# 与unstack()相反stack(),在这里可用于恢复原始系列:
print(pop.unstack().stack()) # 还原

'''指标设置和重置'''

# 重新排列层次结构数据的另一种方法是将索引标签转换为列
# 这可以通过该reset_index方法来完成

pop_flat = pop.reset_index(name='population')
print(pop_flat)
print(pop_flat.set_index(['state', 'year']))

'''多指标上的数据聚合'''

# 每年两次访问中的测量结果进行平均。
data_mean = health_data.mean(level='year')
print(data_mean)

# 使用axis关键字,我们还可以在列的各个级别之间取均值
print(data_mean.mean(axis=1, level='type'))
打赏
赞(0) 打赏
未经允许不得转载:同乐学堂 » 原创-Pandas心法之分层索引-4

特别的技术,给特别的你!

联系QQ:1071235258QQ群:710045715

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

error: Sorry,暂时内容不可复制!