python学习之数据科学库

numpy创建数组

#导入numppy库, 对numpy重命名为np。
import numpy as np

#1). 创建数组: a, b, c创建的数组相同, 任选一种;
#方法一: 直接将数组/列表传入array方法中, 将数据类型转换为ndarray.
a = np.array([1, 2, 3, 4, 5])
 #array方法传入的值可以是range对象
b = np.array(range(1, 6))
print(b)
li = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11.8, 12]
]
#转换数据类型时可以通过dtype对数组的所有对象转换类型. eg: dtype=np.int将元素转成int
li_ndarray = np.array(li, dtype=np.int)

#方法二: 直接生成指定的数值
c = np.arange(1, 6)
##arange和range的基本语法和参数一致。 arange的优点: 可以生成小数区间.
#d = np.arange(2.2, 13.3, 0.2)
#print(a, b, c)

##2). 查看numpy创建的数组类型
print(type(a))
print(type(b))
print(type(c))

#3). 查看数组存储的数据类型, 常见的数据类型还有哪些?
print(a.dtype)   # 为什么是int64? 因为硬件架构是64位;

#4). 制定创建的数组的数据类型
d = np.array([1.9, 0, 1.3, 0], dtype=np.float)
print(d, d.dtype)
#5). 修改数组的数据类型
e = d.astype('int64')   # 里面可以是数据类型, 也可以是数据代码;int64---i1
print(e, e.dtype)

#6). 修改浮点数的小数点位数
#随机创建一个三行四列的数组;
f = np.random.random((3, 4))
print(f)

#修改浮点值的小数位数为3位
g = np.round(f, 3)
print(g)

矩阵的转置

import numpy as np

#size = (3, 4) , 生成一个0~1之间的数值, 数值的个数3*4=12个.
#12 = 1*12 = 2*6 = 3*4 = 4*3 = 6*2 = 12*1
#data = np.random.random(size=(3, 4))
data = np.random.random((3, 4))

#转换数据结构 # 2,6
data = data.reshape((2, 6))

"""
什么叫转置?
    1). 原先矩阵的行变成现在矩阵的列
    2). 将A的所有元素绕着一条从第1行第1列元素出发的右下方45度的射线作镜面反转,即得到A的转置。

案例: 
    # 3*2
    a = [
         [1, 2], 
         [3, 4], 
         [5, 6],    
    ]    

    #转置
    b = [
        1   3   5 
        2   4   6
    ]  
"""
print(data)
print(data.shape)
print("转置: ", data.T)
print("转置: ", data.transpose())
#numpy里面轴分为0轴(x行)和1轴(y列)
print("转置: ", data.swapaxes(1, 0))

numpy的索引和切片

import numpy as np

#1). 生成测试数据
#np.arange(12)  ==> ndarray:[0 1 2 3 4 5 6 7 8 9 10 11]
#reshape((3, 4))  ===>
a = np.arange(12).reshape((3, 4))

print(a)

#*****************取单行或者单列*********************
#取第2行; a[i]=> 获取第i+1行
print("第2行内容: ", a[1])
#取第3列;a[:,i] => 获取第i+1列
print("第2列内容: ",a[:, 2])
#获取第2行3列的数据; a[i, j] ===> 获取第i+1行j+1列
print("第2行3列的内容: ", a[1, 2])

#*****************取连续行或者列*********************
#取第2行和第3行; a[i:j]===> 获取第i+1行到第j行
print(a[1:3])

#取第3列和第4列; a[:, i:j] ===> 获取第i+1列到第j列
print(a[:, 2:4])

#行: 1和2   列: 2, 获取前2行里面的第2列
print(a[0:2, 1:2])

"""
需求:拿出2*2的数组
    1 2
    5 6 
1). 先获取前2行
2). 在前2行的基础上获取第2列和第3列      
"""
print(a[:2, 1:3])

#*****************取不连续的行或者列*********************
#行: 1和3   列: all 获取第一行和第三行的所有元素
print(a[[0, 2], :])
#行: all   列: 1, 4
print(a[:, [0, 3]])
#行: 1 , 3   列: 1 4  获取第一行第一列的元素, 和第三行第4列的元素
print("*"*10)
print(a[[0, 2], [0, 3]])

numpy数值的修改

import numpy as np

#执行行和指定列的修改
t = np.arange(24).reshape((4, 6))
print(t)

#方法一: 根据索引/切片对元素进行赋值。
#行: all, 列: 3,4
#索引的思路: 2~4-1  列: 3~4
#行/列的位置: 3~4
t[:, 2:4] = 0
print(t)

#方法二: 布尔索引, 满足条件/Bool=True,则赋值, 否则, 不做修改
#返回的是矩阵(和t的size一样), 存储的是Bool类型
print(t < 10)

t[t < 10] = 100
print(t)

t[t > 20] = 200
print(t)

#方法三: numpy的三元运算符 t<100?0:10
# 满足条件/Bool=True,则赋值=value1, 否则,赋值=value2
t1  = np.where(t < 100, 0, 10)
print(t)
print(t1)

获取矩阵的四角元素

"""
获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]。

 1 2 3 4
 5 6 7 8
 9 10 11

"""

import numpy as np
def get_edge(data):
    """获取了数组中的四个角的元素"""
    row, column = data.shape
    rows = np.array([[0, 0], [row - 1, row - 1]])
    cols = np.array([[0, column - 1], [0, column - 1]])
    return  data[rows, cols]

if __name__ == '__main__':
    x = np.arange(30).reshape((5, 6))
    print("data:", x)
    print("result: ", get_edge(x))

#x = np.arange(12).reshape((4, 3))
#print('我们的数组是:')
#print(x)
##获取四角元素, 它对应的索引是什么?
##0=(0,0)  2=(0,2) 9=(3,0)  11=(3,2)

#row, column = x.shape  # row=4 column=3
##rows = np.array([[0, 0], [3, 3]])   # 获取的行信息
##cols = np.array([[0, 2], [0, 2]])   # 获取的列信息

#rows = np.array([[0, 0], [row-1, row-1]])
#cols = np.array([[0, column-1], [0, column-1]])
#y = x[rows, cols]
#print('这个数组的四个角元素是:')
#print(y)

数组形状的修改


"""
    reshape 不改变数据的条件下修改形状
         numpy.reshape(arr, newshape, order='C')
         order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。
    flat    数组元素迭代器

    flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
    ravel   返回展开数组
"""

import numpy as np

print("****************************************flat********************************")
a = np.arange(9).reshape(3, 3)
print('原始数组:')
for row in a:
    print(row)

##对数组中每个元素都进行处理(展开),可以使用flat属性,该属性是一个数组元素迭代器:
print('迭代后的数组:')
for element in a.flat:
    print(element)

print("*********************************flatten**************************************")
a = np.arange(8).reshape(2, 4)

print('原数组:')
print(a)
print('\n')
 默认按行

print('展开的数组:')
print(a.flatten())
print('\n')

print('以 F 风格顺序展开的数组:')
print(a.flatten(order='F'))

print("*********************************ravel*************************************")
a = np.arange(8).reshape(2, 4)

print('原数组:')
print(a)
print('\n')

print('调用 ravel 函数之后:')
print(a.ravel())
print('\n')

print('以 F 风格顺序调用 ravel 函数之后:')
print(a.ravel(order='F'))

数组拼接

"""
concatenate 连接沿现有轴的数组序列
stack   沿着新的轴加入一系列数组。
hstack  水平堆叠序列中的数组(列方向)
vstack  竖直堆叠序列中的数组(行方向)

"""

import numpy as np

print("******************** concatenate ****************")
a = np.array([[1, 2], [3, 4]])
print('第一个数组:')
print(a)
print('\n')

b = np.array([[5, 6], [7, 8]])
print('第二个数组:')
print(b)
print('\n')

##两个数组的维度相同
##x轴和y轴, 0轴和1轴
#print('沿轴 0 连接两个数组:')
print(np.concatenate((a, b)))
print('\n')

#print('沿轴 1 连接两个数组:')
print(np.concatenate((a, b), axis=1))

 print("*************************stack*********************************")
#a = np.array([[1, 2], [3, 4]])
#print('第一个数组:')
#print(a)
#print('\n')
#b = np.array([[5, 6], [7, 8]])

#print('第二个数组:')
#print(b)
#print('\n')
#print('沿轴 0 堆叠两个数组:')
#stack_0 = np.stack((a, b), axis=-1)
#print(stack_0)
#print(stack_0.shape)
#print('\n')
#print('沿轴 1 堆叠两个数组:')
#print(np.stack((a, b), axis=1))

print("**************************************hstack + vstack*************************************")
a = np.array([[1, 2], [3, 4]])

print('第一个数组:')
print(a)
print('\n')
b = np.array([[5, 6], [7, 8]])

print('第二个数组:')
print(b)
print('\n')

print('水平堆叠:')
c = np.hstack((a, b))
print(c)
print('\n')

print('竖直堆叠:')
c = np.vstack((a, b))
print(c)
print('\n')

数组分割


"""
    split   将一个数组分割为多个子数组
        numpy.split(ary, indices_or_sections, axis)
    hsplit  将一个数组水平分割为多个子数组(按列)
    vsplit  将一个数组垂直分割为多个子数组(按行)
"""

import numpy as np

print("**********************split******************************")
a = np.arange(9)
print('第一个数组:')
print(a)
print('\n')

print('将数组分为三个大小相等的子数组:')
b = np.split(a, 3)
print(b)
print('\n')

print('将数组在一维数组中表明的位置分割:')
b = np.split(a, [1, 7])
print(b)

print('******************hsplit*****************')
harr = np.arange(12).reshape((3, 4))
print('原array:')
print(harr)

print('横向拆分后:')
print(np.hsplit(harr, 2))

print("***************************vsplit****************************")

a = np.arange(12).reshape(4, 3)

print('第一个数组:')
print(a)
print('\n')

print('竖直分割:')
b = np.vsplit(a, 2)
print(b)

数组元素的添加与删除

"""
    resize  返回指定形状的新数组
    append  将值添加到数组末尾
    insert  沿指定轴将值插入到指定下标之前
    delete  删掉某个轴的子数组,并返回删除后的新数组
    unique  查找数组内的唯一元素
            arr:输入数组,如果不是一维数组则会展开
            return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
            return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数

"""
import numpy as np

print('***************append****************')
a = np.array([[1, 2, 3], [4, 5, 6]])

print('第一个数组:')
print(a)
print('\n')

print('向数组添加元素:')
#没有指定行/列追加元素时, 默认先把前面的元素展开,再追加
print(np.append(a, [7, 8, 9]))      # [1 2 3 4 5 6 7 8 9]
print('\n')

print('沿轴 0 添加元素:')
print(np.append(a, [[7, 8, 9]], axis=0))
print('\n')

print('沿轴 1 添加元素:')
print(np.append(a, [[5, 5, 5], [7, 8, 9]], axis=1))

print('******************************insert****************************************')
a = np.array([[1, 2], [3, 4], [5, 6]])

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.insert(a, 3, [11, 12]))
print('\n')

print('传递了 Axis 参数。 会广播值数组来配输入数组。')
print('沿轴 0 广播:')
print(np.insert(a, 1, [11, 100], axis=0))
print('\n')

print('沿轴 1 广播:')
print(np.insert(a, 1, [11,12, 13], axis=1))

print('***********************delete******************************************')
a = np.arange(12).reshape(3, 4)

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.delete(a, 5))
print('\n')

print('删除第二列:')
print(np.delete(a, 1, axis=1))
print('\n')

print('删除第二行:')
print(np.delete(a, 1, axis=0))
print('\n')

print('包含从数组中删除的替代值的切片:')
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
"""
np.s_ 为阵列建立索引元组的一种更好的方法。 返回的时slice对象;
也可以使用`Slice()‘加上一些特殊的对象来完成所有这些操作但这个版本更简单,因为它使用了标准的数组索引语法。
"""
print(np.delete(a, np.s_[::2]))

print("删除二维数组")
data = np.arange(12).reshape((3, 4))
print("数组元素:")
print(data)
#行:  列: 2列开始
print(np.delete(data, np.s_[::2], axis=0))
print(np.delete(data, np.s_[::2], axis=1))

print('****************************unique**********************************************')

a = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])

print('第一个数组:')
print(a)
print('\n')

print('第一个数组的去重值:')     # [2 5 6 7 8 9]
u = np.unique(a)
print(u)
print('\n')

print('去重数组的索引数组:')     # [a.index(2), a.index(5), ........a.index(9)]
u, indices = np.unique(a, return_index=True)
print(indices)
print('\n')

print('返回去重元素的重复数量:')
u, indices = np.unique(a, return_counts=True)
print(u)
print(indices)

numpy统计函数

"""
numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
numpy.ptp()函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
numpy.percentile() 百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)

#平均值, 各个值的比重/权重一样. 语文: 100 数学:70 英语: 80 (100+70+80)/3
numpy.mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。
#加权平均值, 各个值的比重/权重不一样. 语文: 100 (40%)数学:70(40%) 英语: 80(20%) (10040%+7040%+80*20%)/3
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。 average()

np.std() 标准差是一组数据平均值分散程度的一种度量。
标准差公式如下:std = sqrt(((x - x.mean())2))/n
np.var() 统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 ((x - x.mean())
2)/n。
标准差是方差的平方根。

# numpy学生身高体重统计分析案例
需求1:
    获取所有男生的身高, 求平均值;获取所有女生的身高, 求平均值;并绘制柱状图显示
    1). 读取文件中的Sex和Height
    2). 根据布尔索引判断姓名, 获取男性的身高或者女性的身高  data['gender'] == 'M'
    3). 求平均值mean函数

需求2:
    获取所有男生的体重, 求平均值;获取所有女生的体重, 求平均值;并绘制柱状图显示

"""
import numpy as np
def get_avg_height():
    fname = "doc/eg6-a-student-data.txt"
            # 定义读取列的数据类型
    dtype = np.dtype([('gender', '|S1'), ('height', 'f2')])
            # 读取文件的第2列和第3列, 前9行忽略;
    data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,
                      usecols=(1, 3))
            # print(data)
                # print(type(data))         # 通过np加载文件, 返回的是ndarray的数据类型
                    # print(data['gender'])     # 获取gender列信息
                        # print(data['height'])     # 获取height列信息

                            # print(data['height'][data['gender'] == b'M'].mean())
                                # print(data['height'][data['gender'] == b'F'].mean())

                            # 判断是否性别为那男的表达式
    isMale = (data['gender'] == b'M')
    male_avg_height = data['height'][isMale].mean()
                # ~代表取反
    female_avg_height = data['height'][~isMale].mean()
    return male_avg_height, female_avg_height
def parser_weight(weight):
    # 对于体重数据的处理, 如果不能转换为浮点数据类型, 则返回缺失值;
    try:
        return  float(weight)
    except ValueError as e:
        return  -99
def get_avg_weight():
    fname = "doc/eg6-a-student-data.txt"
                # 定义读取列的数据类型
    dtype = np.dtype([('gender', '|S1'), ('weight', 'f2')])
                    # 读取文件的第2列和第4列, 前9行忽略;
    data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,
                      usecols=(1, 4), converters={4:parser_weight})

                # 判断是否性别为男的平均身高
    isMale = data['gender'] == b'M'

            # 判断是否性别为男的平均体重
    is_weight_vaild = data['weight'] > 0
    male_avg_weight = data['weight'][isMale & is_weight_vaild].mean()
    female_avg_weight = data['weight'][~isMale & is_weight_vaild].mean()
    return  male_avg_weight, female_avg_weight
if __name__ == '__main__':
    print(get_avg_height())
    print(get_avg_weight())
"""

基于numpy的股价统计分析和应用

#股票数据信息的获取
    1. 网络爬虫
    2. 网站下载: 专门的股票网站, Kaggle(数据分析和机器学习交流的网站)
    3. 使用已经开发好的股票API接口: tushare

data.csv文件中存储了股票的信息, 其中第4-8列,即EXCEL表格中的D-H列,(K线=)
分别为股票的开盘价,最高价,最低价,收盘价,成交量。
分析角度:
    1. 计算成交量加权平均价格
    概念:成交量加权平均价格,英文名VWAP(Volume-Weighted Average Price,成交量加权平均价格)是一个非常重要的经
    济学量,代表着金融资产的“平均”价格。
    某个价格的成交量越大,该价格所占的权重就越大。VWAP就是以成交量为权重计算出来的加权平均值。

    2. 计算最大值和最小值: 计算股价近期最高价的最大值和最低价的最小值
    3. 计算股价近期最高价的最大值和最小值的差值;----(极差)
    计算股价近期最低价的最大值和最小值的差值
    4. 计算收盘价的中位数
    5. 计算收盘价的方差
    6. 计算对数收益率, 股票收益率、年波动率及月波动率
     ***收盘价的分析常常是基于股票收益率的。
     股票收益率又可以分为简单收益率和对数收益率。
            简单收益率:是指相邻两个价格之间的变化率。  diff
            对数收益率:是指所有价格取对数后两两之间的差值。
            #[1, 2,3 4]   ======>[-1, ]
    ***使用的方法: NumPy中的diff函数可以返回一个由相邻数组元素的差值构成的数组。
    不过需要注意的是,diff返回的数组比收盘价数组少一个元素。
    ***在投资学中,波动率是对价格变动的一种度量,历史波动率可以根据历史价格数据计算得出。计算历史波动率时,需要用
    到对数收益率。
        年波动率等于对数收益率的标准差除以其均值,再乘以交易日的平方根,通常交易日取252天。
        月波动率等于对数收益率的标准差除以其均值,再乘以交易月的平方根。通常交易月取12月。
    7. 获取该时间范围内交易日周一、周二、周三、周四、周五分别对应的平均收盘价
    8. 平均收盘价最低,最高分别为星期几

"""
import numpy as np

print("**********************************************")

#收盘价,成交量
endPrice, countNum = np.loadtxt(
    fname="doc/data.csv",
    delimiter=",",  # 指定文件分隔符;
    usecols=(6, 7),
    unpack=True)
#print(endPrice, countNum)
VWAP = np.average(endPrice, weights=countNum)  # 价格的权重和成交量成正比
print("1. 计算成交量加权平均价格:", VWAP)

print("**********************************************")

#最高价和最低价
highPrice, lowPrice = np.loadtxt(
    fname="doc/data.csv",
    delimiter=",",
    usecols=(4, 5),
    #对于返回的数据进行解包, 有几列信息返回几个数据, 解包几个数据。
    unpack=True
)

print(highPrice, lowPrice)
#最高价的最大值和最低价的最小值
print("2.最高价的最大值: ", highPrice.max())
print("2.最低价的最小值: ", lowPrice.min())

print("**********************************************")
#计算股价近期最高价的最大值和最小值的差值;----(极差)
#计算股价近期最低价的最大值和最小值的差值

print("3. 近期最高价的极差: ", np.ptp(highPrice))
print("3. 近期最低价的极差: ", np.ptp(lowPrice))

print("**********************************************")
#计算收盘价的中位数
print("4. 计算收盘价的中位数:", np.median(endPrice))

print("**********************************************")
#计算收盘价的方差
print("5. 计算收盘价的方差:", np.var(endPrice))

print("**********************************************")

def get_week(date):
    """根据传入的日期28-01-2011获取星期数, 0-星期一 1-"""
    from datetime import datetime
    #默认传入的不是字符串, 是bytes类型;
    date = date.decode('utf-8')
    """
    Monday == 0 ... Sunday == 6
    """
    return datetime.strptime(date, "%d-%m-%Y").weekday()
#星期数和收盘价
week, endPrice = np.loadtxt(
    fname="doc/data.csv",
    delimiter=",",
    usecols=(1, 6),
    converters={1: get_week},
    unpack=True
)
#print(week, endPrice)
allAvg = []
for weekday in range(5):
    # 依次判断获取星期一的平均收盘价, .......星期五
    average = endPrice[week == weekday].mean()
    allAvg.append(average)
    print("7. 星期%s的平均收盘价:%s" % (weekday + 1, average))

print(allAvg)

print("**********************************************")
#[12, 23, 34, 45, 56]

print("8.平均收盘价最低是星期", np.argmin(allAvg) + 1)
print("8. 平均收盘价最高是星期", np.argmax(allAvg) + 1)

print("***********************************************************")
#简单收益率
simpleReturn = np.diff(endPrice)
print(simpleReturn)
#对数收益率: 所有价格取对数后两两之间的差值。
logReturn = np.diff(np.log(endPrice))
print("6. 对数收益率:", logReturn)
#年波动率等于对数收益率的标准差除以其均值,再乘以交易日的平方根,通常交易日取252天。
annual_vol = logReturn.std() / logReturn.mean() * np.sqrt(252)
print("6. 年波动率:", annual_vol)
#月波动率等于对数收益率的标准差除以其均值,再乘以交易月的平方根。通常交易月取12月。
month_vol = logReturn.std() / logReturn.mean() * np.sqrt(12)
print("6. 月波动率:", month_vol)

pandas创建series数据类型

"""
Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。
利器之一:Series
    类似于一维数组的对象,是由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。仅由一组数据也可产生简单的Series对象。
利器之二:DataFrame
    是Pandas中的一个表格型的数据结构,包含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型等),DataFrame即有行索引也有列索引,可以被看做是由Series组成的字典。

常见的数据类型:
    - 一维: Series
    - 二维: DataFrame
    - 三维: Panel  ....
    - 四维: Panel4D  .....
    - N维: PanelND  ....

Series是Pandas中的一维数据结构,类似于Python中的列表和Numpy中的Ndarray,不同之处在于:Series是一维的,能存储不同类型的数据,有一组索引与元素对应。
"""

import pandas as pd
import numpy as np
import  string

#查看pandas版本信息
print(pd.__version__)

#********************创建Series对象
#1). 通过列表创建Series对象
array = ["粉条", "粉丝", "粉带"]
#如果不指定索引, 默认从0开始;
s1 = pd.Series(data=array)
print(s1)
#如果不指定索引, 默认从0开始;
ss1 = pd.Series(data=array, index=['A', 'B', 'C'])
print(ss1)

#2). 通过numpy的对象Ndarray创建Series;
n = np.random.randn(5)   # 随机创建一个ndarray对象;
s2 = pd.Series(data=n)
print(s2)
#修改元素的数据类型;
ss2 = s2.astype(np.int)
print(ss2)

#3). 通过字典创建Series对象;字典的所有key值作为索引, 所有的value值作为Series值
#{'key1':'value1', "key2":'value2'}
#字典生成式
dict = {string.ascii_lowercase[i]:i for i in range(10)}
print(dict)
s3 = pd.Series(dict)
print(s3)

Series 基本操作:

编号 属性或方法 描述
1 axes 返回行轴标签列表。
2 dtype 返回对象的数据类型(dtype)。
3 empty 如果系列为空,则返回True。
4 ndim 返回底层数据的维数,默认定义:1。
5 size 返回基础数据中的元素数。
6 values 将系列作为ndarray返回。
7 head() 返回前n行。
8 tail() 返回最后n行。

"""

import pandas as pd
import numpy as np
import string

array = ["粉条", "粉丝", "粉带"]
s1 = pd.Series(data=array)
print(s1)
print(s1.axes) # [RangeIndex(start=0, stop=3, step=1)]
print(s1.dtype)
print(s1.empty) # False
print(s1.ndim ) # 维度1
print(s1.size) # 3
print(s1.values) # 获取所有的value值(不显示索引)

#1). 修改Series索引
print(s1.index)
s1.index = ['A', 'B', 'C']
print(s1)

#2). Series纵向拼接;
array = ["粉条", "粉丝", "westos"]
#如果不指定索引, 默认从0开始;
s2 = pd.Series(data=array)
s3 = s1.append(s2)
print(s3)

#3). 删除指定索引对应的元素;
s3 = s3.drop('C') # 删除索引为‘C’对应的值;
print(s3)

#4). 根据指定的索引查找元素
print(s3['B'])
s3['B'] = np.nan # None, null, pandas数据为空, 或者数据缺失, np.nan
print(s3)

#5). 切片操作 --- 同列表
print(s3[:2]) # 获取前2个元素
print(s3[::-1]) # 元素进行反转
print(s3[-2:]) # 显示最后两个元素

series运算

import numpy as np
import pandas as pd

#values = [0, 1, 2, 3, 4], index=['a', 'b', 'c', 'd', 'e']
s1 = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e'])  # s1.index=[a, b, c, d, e]   s1.value=[0 1 2 3 4]
#values = [2, 3, 4, 5, 6, 7], index=['c', 'd', 'e', 'f', 'g', 'h']
s2 = pd.Series(np.arange(2, 8), index=['c', 'd', 'e', 'f', 'g', 'h'])  # s2.index = [c,d,e,f]

print(s1)
#print(s2)
##*****************按照对应的索引进行计算, 如果索引不同,则填充为Nan;
##加法, 缺失值+ 真实值===缺失值
#print(s1 + s2)
#print(s1.add(s2))

#print(s1 - s2)
#print(s1.sub(s2))

#print(s1 * s2)
#print(s1.mul(s2))

#print(s1 / s2)
#print(s1.div(s2))

#求中位数
print(s1)
print(s1.median())

#求和
print(s1.sum())

#max
print(s1.max())

#min
print(s1.min())

特殊的where方法

import pandas as pd
import numpy as np
import string

#&**********series中的where方法运行结果和numpy中完全不同;
s1 = pd.Series(np.arange(5), index=['a', 'b', 'c', 'd', 'e'])
#判断s1的value值是否大于3, 如果大于3,值不变, 否则,设置为缺失值
print(s1.where(s1 > 3))

#对象中不大于3的元素赋值为10;判断s1的value值是否大于3, 如果大于3,值不变, 否则,设置值为10
print(s1.where(s1 > 3, 10))

#对象中大于3的元素赋值为10;
print(s1.mask(s1 > 3))
print(s1.mask(s1 > 3, 10))
"""

创建dataframe数据类型

Series只有行索引,而DataFrame对象既有行索引,也有列索引
    行索引,表明不同行,横向索引,叫index,
    列索引,表明不同列,纵向索引,叫columns,

"""

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

#方法1: 通过列表创建
li = [
    [1, 2, 3, 4],
    [2, 3, 4, 5]
]

#DataFRame对象里面包含两个索引, 行索引(0轴, axis=0), 列索引(1轴, axis=1)
d1 = pd.DataFrame(data=li, index=['A', 'B'], columns=['views', 'loves', 'comments', 'tranfers'])
print(d1)

#方法2: 通过numpy对象创建
#[0 1 2 3 4 5 6 7]  ====> [[0 1 2 3], [4 5 6 7]]
narr = np.arange(8).reshape(2, 4)
#DataFRame对象里面包含两个索引, 行索引(0轴, axis=0), 列索引(1轴, axis=1)
d2 = pd.DataFrame(data=narr, index=['A', 'B'], columns=['views', 'loves', 'comments', 'tranfers'])
print(d2)

#方法三: 通过字典的方式创建;
dict = {
    'views': [1, 2, ],
    'loves': [2, 3, ],
    'comments': [3, 4, ]

}
d3 = pd.DataFrame(data=dict, index=['粉条', "粉丝"])
print(d3)

#日期操作的特例:
#pd.date_range()
dates = pd.date_range(start='1/1/2019', end='1/08/2019')
print(dates)

#行索引
dates = pd.date_range(start='today', periods=6, freq='2D' ) # periods=6从今天开始向后产生6个日期
print(dates)

#列索引
columns = ['A', 'B', 'C', 'D']
d4 = pd.DataFrame( np.random.randn(6, 4), index=dates, columns=columns)
print(d4)

#一维对象: 建立一个以2019年每一天作为索引, 值为随机数;
dates = pd.date_range(start='1/1/2021', end='1/3/2021', freq='D')
print(dates)
s1 = pd.Series([1, 2, 3], index=dates)
print(s1)

dataframe基础属性和整体情况查询

"""
a)基础属性
    df.shape  #行数、列数
    df.dtype #列数据类型
    df.ndim #数据维度
    df.index #行索引
    df.columns #列索引
    df.values #对象值,二维ndarray数组

b)整体情况查询
    df.head(3) #显示头部几行,默认5行
    df.tail(3) #显示末尾几行,默认5行
    df.info() #相关信息概览:行数、列数、索引、列非空值个数、列类型、内存占用
    df.describe() #快速综合统计结果: 计数、均值、标准差、最大值、四分位数、最小值等

"""

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

narr = np.arange(8).reshape(2, 4)
#DataFRame对象里面包含两个索引, 行索引(0轴, axis=0), 列索引(1轴, axis=1)
d2 = pd.DataFrame(data=narr, index=['A', 'B'], columns=['views', 'loves', 'comments', 'tranfers'])
print(d2)

#**********************1). 查看基础属性***********************
print(d2.shape)  # 获取行数和列数;
print(d2.dtypes)  # 列数据类型
print(d2.ndim)  # 获取数据的维度
print(d2.index)  # 行索引
print(d2.columns)  # 列索引
print(d2.values, type(d2.values))  # 对象的值, 二维ndarray数组;

#******************************2). 数据整体状况的查询*************
print(d2.head(1))  # 显示头部的几行, 默认5行
print(d2.tail(1))  # 显示头部的尾行, 默认5行

print("*" * 10)
#相关信息的预览: 行数, 列数, 列类型, 内存占用
print("info:", d2.info())

print("统计".center(50, '*'))
#快速综合用计结果: 计数, 均值, 标准差, 最小值, 1/4位数, 中位数, 3/4位数, 最大值;
print(d2.describe())

#3). 转置操作
print("d2: \n", d2)
#print("d2 T: \n", d2.transpose())
print("d2 T: \n", d2.T)
#print("d2 T: \n", d2.swapaxes(1, 0))

#4). 按列进行排序
print(d2)
#按照指定列进行排序, 默认是升序, 如果需要降序显示,设置ascending=False;
print(d2.sort_values(by=["views", 'tranfers'], ascending=False))

#5). 切片及查询
print(d2)
print(d2[:2])  # 可以实现切片, 但是不能索引;
print('1:\n', d2['views'])  # 通过标签查询, 获取单列信息
print('2:\n', d2.views)  # 和上面是等价的;
print(d2[['views', 'comments']])  # 通过标签查询多列信息

#6). 通过类似索引的方式查询;
        #       - iloc(通过位置进行行数据的获取),
        #        - loc(t通过标签索引行数据)
            # print(d2[0])
                # print(d2)
print(d2.iloc[0])
print(d2.iloc[-1])

            # print(d2['A'])    # 报错
print(d2)
print(d2.loc['A'])

        # 7). 更改pandas的值;
d2.loc['A'] = np.nan
print(d2)

print(d2.info())

文件的读取与写入

import os

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

#csv, excel, json........
#). csv文件的写入

df = pd.DataFrame(
    {'province': ['陕西', '陕西', '四川', '四川', '陕西'],
     'city': ['咸阳', '宝鸡', '成都', '成都', '宝鸡'],
     'count1': [1, 2, 3, 4, 5],
     'count2': [1, 2, 33, 4, 5]
     }
)

print(df)

filename = os.path.join('doc', 'csvFile.csv')
"""
index=True/False   是否存储行索引, 一般情况下不存储
mode='w'           文件写入的方式, 默认是'w'(清空原有的文件内容, 再写入), 'a'追加
header=True/False  是否写入头部信息(列索引), 一般情况是需要的
"""
#df.to_csv(filename, index=False, mode='a', header=False, sep=' ')  # index=False不存储行索引
#print("csv文件保存成功")

##2). csv文件的读取
#df2 = pd.read_csv('doc/csvFile.csv')
#print(df2)

#3). excel文件的写入
df.to_excel("doc\excelFile.xlsx", sheet_name="省份统计", index=False)
print("excel文件保存成功")

分组与聚合操作之group_by

"""
pandas提供了一个灵活高效的groupby功能,
    1). 它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。
    2). 根据一个或多个键(可以是函数、数组或DataFrame列>名)拆分pandas对象。
    3). 计算分组摘要统计,如计数、平均值、标准差,或用户自定义函数。

"""

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

df = pd.DataFrame(
    {'province': ['陕西', '陕西', '四川', '四川', '陕西'],
     'city': ['咸阳', '宝鸡', '成都', '成都', '宝鸡'],
     'count1': [1, 2, 3, 4, 5],
     'count2': [1, 2, 33, 4, 5]
     }
)
        # 陕西      咸阳    1
        #          宝鸡     1

print(df)
    # 根据某一列的key值进行统计分析;
grouped = df['count1'].groupby(df['province'])
print(grouped.describe())
print(grouped.median())

    # 根据城市统计分析cpunt1的信息;
grouped = df['count1'].groupby(df['city'])
print(grouped.max())

    # 指定多个key值进行分类聚合;
grouped = df['count1'].groupby([df['province'], df['city']])
print(grouped.max())
print(grouped.sum())
print(grouped.count())

    #  通过unstack方法, 实现层次化的索引;
print(grouped.max().unstack())

案例:商品数据分析案例

"""
文件描述: 每列数据分别代表如下: 订单编号, 订单数量, 商品名称, 商品详细选择项, 商品总价格
需求1:
    1). 从文件中读取所有的数据;  如何读取csv文件? to_csv
    2). 获取数据中所有的商品名称;如何获取dataframe对象中的某一列信息? df['列名'], df.列名称
    3). 跟据商品的价格进行排序, 降序,   如何对df对象排序? d2.sort_values(by=["排序的列名称"], ascending=True)
    将价格最高的20件产品信息写入mosthighPrice.xlsx文件中;   如何获取df的前20行并写入文件? df.head(20)   df1.to_csv(xxxxxx)

需求2:
    1). 统计列[item_name]中每种商品出现的频率,绘制柱状图
            (购买次数最多的商品排名-绘制前5条记录)
    2). 根据列 [odrder_id] 分组,求出每个订单花费的总金额。
    3). 根据每笔订单的总金额和其商品的总数量画出散点图。
"""

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

##需求1:
##1). 从文件中读取所有的数据;
##2). 获取数据中所有的商品名称;
#goodsInfo = pd.read_csv('doc/chipo.csv')
##print(goodsInfo.head())
##print(goodsInfo.tail())
##print(goodsInfo.info())
##print(goodsInfo.describe())
#print("商品名称显示: \n", goodsInfo['item_name'].head())
#print("商品名称显示: \n", goodsInfo.item_name.head())

##需求1:

 #3). 跟据商品的价格进行排序, 降序,
##将价格最高的20件产品信息写入mosthighPrice.xlsx文件中;
##重新赋值;
#goodsInfo.item_price = goodsInfo.item_price.str.strip('$').astype(np.float)
#highPriceData = goodsInfo.sort_values('item_price', ascending=False).head(20)
##print(highPriceData.head(5))
#filename = 'doc\mostHighPrice.xlsx'
#highPriceData.to_excel(filename)
#print("保存成功.......")

#需求2:
#1). 统计列[item_name]中每种商品出现的频率,绘制柱状图
#(购买次数最多的商品排名-绘制前5条记录)
goodsInfo = pd.read_csv('doc\chipo.csv')
#new_info会统计每个商品名出现的次数;其中 Unnamed: 0就是我们需要获取的商品出现频率;
newInfo = goodsInfo.groupby('item_name').count()
mostRaiseGoods = newInfo.sort_values('Unnamed: 0', ascending=False)['Unnamed: 0'].head(5)
print(mostRaiseGoods)       # Series对象

#获取对象中的商品名称;
x = mostRaiseGoods.index
#获取商品出现的次数;
y = mostRaiseGoods.values

#from pyecharts import Bar
#bar = Bar("购买次数最多的商品排名")
#bar.add("", x, y)
#bar.render()
#需求2:
#2). 根据列 [odrder_id] 分组,求出每个订单花费的总金额======订单数量(quantity), 订单总价(item_price)。
#3). 根据每笔订单的总金额和其商品的总数量画出散点图。

goodsInfo = pd.read_csv('doc/chipo.csv')
#获取订单数量
quantity = goodsInfo.quantity
#获取订单item_price价格
item_price = goodsInfo.item_price.str.strip('$').astype(np.float)
print(item_price)

#根据列 [odrder_id] 分组
order_group = goodsInfo.groupby("order_id")
#每笔订单的总金额
x = order_group.item_price.sum()
#商品的总数量
y = order_group.quantity.sum()

字符串常用操作

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

series1= pd.Series(['$A:1', '$B:2', '$C:3', np.nan, '$cat:3'])
print(series1)

#将所有的字母转换为小写字母, 除了缺失值
print(series1.str.lower())

#将所有的字母转换为大写字母, 除了缺失值
print(series1.str.upper())

#分离
print(series1.str.split(":"))

#去掉左右两端的某个字符
print(series1.str.strip('$'))
"""

文件内容: 总消费金额, 小费金额, 性别, 是否抽烟, 日期, 时间, 星期
需求:

  • 分别吸烟顾客与不吸烟顾客的消费金额与小费之间的散点图; #
  • 女性与男性中吸烟与不吸烟顾客的消费金额与小费之间的散点图关系;
    """

消费金额和小费之间的关联与性别和抽烟与否的关系

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

filename = 'doc/tips.csv'
data = pd.read_csv(filename)
#print(data.head())
#print(data.info())

    # # 实现吸烟顾客消费金额与小费之间的散点图
    # smoker = data[data['smoker'] == 'Yes']          # 筛选吸烟的顾客信息
    # x_total_bill1 = smoker['total_bill']
    # y_tip1 = smoker['tip']

##实现不吸烟顾客消费金额与小费之间的散点图
#no_smoker = data[data['smoker'] != 'Yes']
##print(smoker.head())
#x_total_bill2 = no_smoker['total_bill']
#y_tip2 = no_smoker['tip']

#from pyecharts import  Scatter
#scatter = Scatter("吸烟/不吸烟顾客消费金额与小费之间的散点图")
#添加第1个数据信息: x和y
#scatter.add("吸烟", x_total_bill1, y_tip1)
##添加第2个数据信息: x和y
#scatter.add("不吸烟", x_total_bill2, y_tip2)
#scatter.render()

##女性中吸烟与不吸烟顾客的消费金额与小费之间的散点图关系;
is_smoker = data['smoker'] == 'Yes'
is_female = data['sex'] == 'Female'

female_smoker = data[is_female & is_smoker]
female_no_smoker = data[is_female & ~is_smoker]
male_smoker = data[~is_female & is_smoker]
male_no_smoker = data[~is_female & ~is_smoker]

#3). 绘制散点图
from pyecharts import  Scatter
scatter = Scatter("消费金额与小费之间的散点图")
scatter.add("吸烟女顾客", female_smoker['total_bill'], female_smoker['tip'])
scatter.add("不吸烟女顾客", female_no_smoker['total_bill'], female_no_smoker['tip'])
scatter.add("吸烟男顾客", male_smoker['total_bill'], male_smoker['tip'])
scatter.add("不吸烟男顾客", male_no_smoker['total_bill'], male_no_smoker['tip'])

scatter.render()

猜你喜欢

转载自blog.51cto.com/13810716/2492178
今日推荐