import pandas as pd
from pandas import Series, DataFrame
import numpy as np

"""
Explanation: pandas含有使数据分析工作变得更快更简单的高级数据结构和操作工具。pandas基于NumPy构建，让以NumPy为中心的应用变得更加简单。
End of explanation
"""


obj = Series([4, 7, -5, 3])
obj
# Series的字符串表现形式为：索引在左边，值在右边。
# 由于我们没有为数据指定索引，于是会自动创建一个0到N-1的整数索引

# 获取Series的values和index属性
obj.values

obj.index

# 创建Series带有可以对各个数据点进行标记的索引
obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2

obj2.index

obj2['a']

"""
Explanation: 1. Pandas的数据结构
pandas的两个主要数据结构是：Series和DataFrame。
1.1 Series
Series是一种类似于一维数组的对象，它由一组数据（各种NumPy数据类型）以及一组与之相关的数据索引组成。
1. Series的构建
End of explanation
"""


obj2

# 布尔表达式过滤
obj2[obj2 > 0]

# 标量乘法
obj2 * 2

# 应用数学函数
np.exp(obj2)

"""
Explanation: 2. NumPy数组运算
End of explanation
"""


'b' in obj2

'e' in obj2

"""
Explanation: 将Series看成是一个定长的有序字典，因为它是索引值到数据值的一个映射。
End of explanation
"""


sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
# 传入Python字典，原字典的键成为Series的索引
obj3 = Series(sdata)
obj3

sindex = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = Series(sdata, index=sindex)
# sdata中跟states索引项匹配的值会被找出来并放到相应的位置上
obj4

obj4.isnull()

"""
Explanation: 3. 通过Python字典创建Series
End of explanation
"""


obj3 + obj4

"""
Explanation: 4. Series自动对齐
End of explanation
"""


obj4.name = 'population'
obj4.index.name = 'state'
obj4

"""
Explanation: 5. Series的name属性
End of explanation
"""


obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
obj

"""
Explanation: 6. 修改Series的索引
End of explanation
"""


data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = DataFrame(data)
frame
# DataFrame会自动加上索引，且全部被有序排列

# 如果指定列序列，则DataFrame的列就会按照指定顺序进行排列
DataFrame(data, columns=['year', 'state', 'pop'])

# 如果传入的列在数据中找不到，就会产生NA值
frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
         index=['one', 'two', 'three', 'four', 'five'])
frame2

"""
Explanation: 1.2 DataFrame
DataFrame是一个表格型的数据结构，它含有一组有序的列，每列可以是不同的值类型。DataFrame既有行索引也有列索引，它可以被看做由Series组成的字典（功用同一个索引）。
1. 构建DataFrame
最常用是直接传入一个由等长列表或NumPy数组组成的字典
End of explanation
"""


frame2['state']

frame2.year

"""
Explanation: 2. 对DataFrame的行和列的操作
通过类似字典标记的方式或属性的方式，可以将DataFrame的列获取为一个Series
End of explanation
"""


frame2.ix['three']

"""
Explanation: 返回的Series拥有原DataFrame相同的索引，且其name属性已经被设置好了
用索引字段ix可以获得DataFrame的一行
End of explanation
"""


frame2['debt'] = 16.5

frame2

"""
Explanation: 列可以通过赋值的方式进行修改
End of explanation
"""


frame2['debt'] = [1, 2, 3, 4, 5]
frame2

val = Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame2['debt'] = val
frame2

"""
Explanation: 将列表或数组赋值给某个列时，其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series，就会精确匹配DataFrame的索引
End of explanation
"""


frame2['eastern'] = frame2.state == 'Ohio'

frame2

"""
Explanation: 为不存在的列赋值会创建出一个新列
End of explanation
"""


del frame2['eastern']

frame2.columns

frame2

"""
Explanation: 关键字del用于删除列
End of explanation
"""


pop = {'Nevada': {2001: 2.4, 2002: 2.9},
      'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = DataFrame(pop)
frame3

# 对结果进行转置
frame3.T

"""
Explanation: 通过索引方式返回的列只是相应数据的视图而已，并不是副本。对返回的Series所做的任何修改都会反映到原DataFrame上。通过Series的copy方法即可显式地复制列。
3. 传给DataFrame嵌套字典
如果数据形式是嵌套字典（字典的字典），将它传给DataFrame，它会被解释为：外层的键作为列，内层的键则作为行索引。
End of explanation
"""


# 设置DataFrame的index和columns的name属性，并显示出来
frame3.index.name = 'year'
frame3.columns.name = 'state'
frame3

"""
Explanation: 可以输入给DataFrame构造器的数据：
- 二维ndarray： 数据矩阵
- 由数组、列表或元组组成的字典： 每个序列会变成DataFrame的一列。所有序列的长度必须相同
- NumPy的结构化/记录数组： 类似于 有数组组成的字典
- 由Series组成的字典
- 由字典组成的字典
- 字典或Series的列表
- 由列表或元组组成的列表
- 另一个DataFrame
- NumPy的MaskedArray
4. DataFrame的属性
End of explanation
"""


frame3.values

"""
Explanation: DataFrame的values属性会以二维ndarray的形式返回DataFrame中的数据
End of explanation
"""


obj = Series(range(3), index=['a','b','c'])
index = obj.index
index

index[1:]

"""
Explanation: 2. 索引对象
pandas的索引对象负责轴标签和其他元数据(比如轴名称等)，构建Series或DataFrame时， 所用到的任何数组或其他序列的标签都会被转换成一个Index。Index对象是
End of explanation
"""


