2019-11-01 14:17:53 qq_36853469 阅读数 3346
  • Python基础

    Python 以其简洁、优雅、高效的特点,成为目前流行的4大主流开发语言之一,其应用广泛,易学易用,让很多人爱不释手。本套课程为初学者量身打造,是你入门 Python 的必修课程。这一部分内容涵盖了Python基础的知识点,包括Python的基础语法,比如变量,字符编码等,数据类型以及if else,for循环等流程控制语句,内容简单却十分关键,无论是数据类型还是控制语句都是在以后的Python学习无论方向都会反复大量应用的。 此课程特别适合之前完全无任何开发经验的小白白学习! Python除了是人工智能领域第一语言之外,其实还广泛的应用于WEB开发、云计算、金融分析、自动化运维、自动化测试、爬虫、大数据分析等领域,生态圈极为丰富和活跃。它强大的模块库大大的提高了开发者的开发效率,简洁明朗的语法使写代码如写诗一样优雅顺畅,极大降低了编程的学习门槛。可以不谦虚的说,Python是唯一一门无论是开发老司机还是小白白都一致称赞的编程语言。 不论你是什么背景出身,如果对编程感兴趣,从Python入手吧,Python是检测你是否适合做程序员的好的语言,如果练Python都学不会,哈哈,那你可以放弃这个职业啦!

    14317 人正在学习 去看看 李杰

 

1.NumPy简介及其使用

  • NumPy是一个功能强大的Python库,主要用于对多维数组执行计算,允许更高级的数据操作和数学计算。 它包括数学、逻辑、数组形状变换、排序、选择、I/O 、离散傅立叶变换、基本线性代数、基本统计运算、随机模拟等等。
    • 机器学习模型:在编写机器学习算法时,需要对矩阵进行各种数值计算。例如矩阵乘法、换位、加法等。NumPy提供了一个非常好的库,用于简单(在编写代码方面)和快速(在速度方面)计算。NumPy数组用于存储训练数据和机器学习模型的参数。
    • 图像处理和计算机图形学:计算机中的图像表示为多维数字数组。NumPy成为同样情况下最自然的选择。实际上,NumPy提供了一些优秀的库函数来快速处理图像。例如,镜像图像、按特定角度旋转图像等。
    • 数学任务:NumPy对于执行各种数学任务非常有用,如数值积分、微分、内插、外推等。因此,当涉及到数学任务时,它形成了一种基于Python的MATLAB的快速替代。
  • Numpy安装:在shell上使用以下命令:pip install numpy

2.Numpy基础知识

  • NumPy的数组类被称为ndarray。别名为 array。 请注意,numpy.array 与标准Python库类 array.array 不同,后者仅处理一维数组并提供较少的功能。 ndarray 对象则提供更关键的属性:
    • ndarray.ndim:数组的轴(维度)的个数。在Python世界中,维度的数量被称为rank。
    • ndarray.shape:数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于有n行和m列的矩阵,shape将是(n,m)。因此,shape元组的长度就是rank或维度的个数 ndim
    • ndarray.size:数组元素的总数。这等于shape的元素的乘积。
    • ndarray.dtype:一个描述数组中元素类型的对象。可以使用标准的Python类型创建或指定dtype。另外NumPy提供它自己的类型。例如numpy.int32、numpy.int16和numpy.float64。
    • ndarray.itemsize:数组中每个元素的字节大小。例如,元素为 float64 类型的数组的 itemsize 为8(=64/8),而 complex32 类型的数组的 itemsize 为4(=32/8)。它等于 ndarray.dtype.itemsize 。
    • ndarray.data:该缓冲区包含数组的实际元素。通常,我们不需要使用此属性,因为我们将使用索引访问数组中的元素。

3.NumPy的使用及其方法

# -*- coding: utf-8 -*-
"""
Author :        Jason
"""
__author__ = 'Jason'
'''
NumPy是Python的一个用于科学计算的基础包,属于Python的第三方库。
NumPy包的核心是ndarray对象。它封装了n维同类数组,特别注意这里的数组必须是同类型。
个人理解: 结合现代中的矩阵最好理解了
使用前先安装 pip3 install numpy
'''
import numpy as np 
data1 = [1,2,3,4,5]
array1 = np.array(data1)
print(type(array1),"\n",array1)
'''
<class 'numpy.ndarray'> 
 [1 2 3 4 5]
'''

data2 = [[1,2,3],[4,5,6]]
array2 = np.array(data2)
print(array2)
'''
[[1 2 3]
 [4 5 6]]
'''

#查询内部元素类型
print(array1.dtype)                 # int32
print(array2.dtype)                 # int32

#转换数据类型
print(array1.astype("str"))       # ['1' '2' '3' '4' '5']
print(array1.astype("str").dtype) # <U11

#数组的运算
print(array1 + 1)       # [2 3 4 5 6]
print(array1 * 2)       # [ 2  4  6  8 10]
print(array1 * array1)  # [ 1  4  9 16 25]
print(array1 / 5)       #[0.2 0.4 0.6 0.8 1. ]

#array数组的访问方式和Python列表的访问方式相同,下标索引切片等
print(array1[3])        # 4
print(array1[0:2])      # [1 2]
print(array1[:2])       # [1 2]
print(array1[-2:])      # [4 5]

#矩阵元素的个数
print(array1.size)  # 5
print(array1.itemsize) #一个元素的长度(以字节为单位)


#NumPy自带函数创建ndarray数组
data1 = np.ones(4)           # 自带函数ones(参数一维个数)
data2 = np.zeros(4)          # 自带函数zeros(参数一维个数)
data3 = np.random.random(4)  # 自带函数random.random(参数一维个数)
print("data1,data2,data3:",data1,data2,data3)
data4 = np.full(3,4)         # [4 4 4]
print(data4)                 # 创建一个长度为3,元素全为4的数组
data5 = np.eye(4)            # 创建一个正方形4*5单位矩阵,对角线为1,其余为0
print(data5)
data6 = np.linspace(0,10,3)	             ##第一个值为起始值,第二个值为结束值,第三个值为元素个数
print(data6)                             #[0 5 10]
data7 = np.linspace((10,10,10),(0,0,0),3)#第一个值为起始值,第二个值为结束值,第三个值为元素个数,这里把一维数组看作一个元素比较好理解
print(data7)
'''
[[10. 10. 10.]
 [ 5.  5.  5.]
 [ 0.  0.  0.]]
'''

#数组维度变换
'''
np.reshape(shape)	不改变数组元素,返回一个shape形状的数组,原数组不变
np.resize(shape)	同上,但是是修改了原数组
np.swapaxes(ar1,ar2)	将数组n各维度中的两个维度进行调换
np.flatten()	对数组降维,返回一维数组,原数组不变
'''

#获取平均值mean(),最大值max(),最小值min(),和sum()
print(array1.mean()) #3
print(array1.min())  #1
print(array1.max())  #5
print(array1.sum())  #15

参照:《基于Python的大数据分析基础及实战》

 

2018-02-20 22:11:01 songyunli1111 阅读数 790
  • Python基础

    Python 以其简洁、优雅、高效的特点,成为目前流行的4大主流开发语言之一,其应用广泛,易学易用,让很多人爱不释手。本套课程为初学者量身打造,是你入门 Python 的必修课程。这一部分内容涵盖了Python基础的知识点,包括Python的基础语法,比如变量,字符编码等,数据类型以及if else,for循环等流程控制语句,内容简单却十分关键,无论是数据类型还是控制语句都是在以后的Python学习无论方向都会反复大量应用的。 此课程特别适合之前完全无任何开发经验的小白白学习! Python除了是人工智能领域第一语言之外,其实还广泛的应用于WEB开发、云计算、金融分析、自动化运维、自动化测试、爬虫、大数据分析等领域,生态圈极为丰富和活跃。它强大的模块库大大的提高了开发者的开发效率,简洁明朗的语法使写代码如写诗一样优雅顺畅,极大降低了编程的学习门槛。可以不谦虚的说,Python是唯一一门无论是开发老司机还是小白白都一致称赞的编程语言。 不论你是什么背景出身,如果对编程感兴趣,从Python入手吧,Python是检测你是否适合做程序员的好的语言,如果练Python都学不会,哈哈,那你可以放弃这个职业啦!

    14317 人正在学习 去看看 李杰

数据结构是计算机存储、组织数据的方式。不同语言只是数据结构实现的不同工具,但本质是一样的。

Python的强大之处在于其自带的数据结构:列表 list,元组 tuple,字典 dict 等,都非常的强大,尤其是列表,在它们的基础上可以方便快捷的实现常用的数据结构:栈,队列,链表,树等,而没有必要重复造轮子。

栈和队列

栈,是一种仅允许在表的一端进行插入和删除运算的受限线性表,满足后进先出原则。

队列,是一种仅允许在表的前端进行删除操作,而在表的后端进行插入操作的受限线性表,满足先进先出原则。

Python 中的列表,其自有的 insert() 函数可以在任意位置插入, pop() 函数可以在任意位置弹出并删除。

因此,在 Python 中,栈和队列可以用列表实现。

链表和树

链表,是一种在逻辑上连续,但在物理存储单元上不一定连续的线性存储结构。包括存储数据元素的数据域和存储下一个节点地址的指针域。

树,是一种典型的非线性结构,可以用来表示层次关系,因表示的样子很像一颗倒立的树而得名。

在树中,最简单也是应用最广泛的是二叉树,同样包括存储数据元素的数据域和存储左右孩子节点地址的指针域。

在C语言中,因为指针的加持,可以很直观的实现链表和树等需要指针的数据结构,而在 Python 中,虽然没有显式的指针,但每个变量,除了基本数据类型(int,float 等),都是一个『引用』。

引用:当你创建一个对象并给它赋一个变量的时候,这个变量仅仅引用那个对象,而不是表示这个对象本身!也就是说,变量名指向你计算机中存储那个对象的内存。这被称作名称到对象的引用。

可以看出,引用类似于指针,只是不能进行指针运算,比如, p + 1 指向下一个元素之类的。

因此,在 Python 中,链表和树可以通过定义节点类和引用来实现。

说明

在本专栏接下来的文章中,会用 Python 去实现基本的数据结构:栈,队列,链表和树,并都会附上一个小的应用实例。然后结合剑指offer 中的数据结构相关笔试题,用 Python 来完成,以更好地延伸到数据结构更多的操作和实践中去,希望本专栏能助你在 Python 编程学习之路一臂之力。

本专栏许多内容参考自经典书籍:Problem Solving with Algorithms and Data Structures using Python 在此对作者深表感谢!

2019-11-01 15:08:22 qq_36853469 阅读数 3365
  • Python基础

    Python 以其简洁、优雅、高效的特点,成为目前流行的4大主流开发语言之一,其应用广泛,易学易用,让很多人爱不释手。本套课程为初学者量身打造,是你入门 Python 的必修课程。这一部分内容涵盖了Python基础的知识点,包括Python的基础语法,比如变量,字符编码等,数据类型以及if else,for循环等流程控制语句,内容简单却十分关键,无论是数据类型还是控制语句都是在以后的Python学习无论方向都会反复大量应用的。 此课程特别适合之前完全无任何开发经验的小白白学习! Python除了是人工智能领域第一语言之外,其实还广泛的应用于WEB开发、云计算、金融分析、自动化运维、自动化测试、爬虫、大数据分析等领域,生态圈极为丰富和活跃。它强大的模块库大大的提高了开发者的开发效率,简洁明朗的语法使写代码如写诗一样优雅顺畅,极大降低了编程的学习门槛。可以不谦虚的说,Python是唯一一门无论是开发老司机还是小白白都一致称赞的编程语言。 不论你是什么背景出身,如果对编程感兴趣,从Python入手吧,Python是检测你是否适合做程序员的好的语言,如果练Python都学不会,哈哈,那你可以放弃这个职业啦!

    14317 人正在学习 去看看 李杰

1.Pandas简介

Pandas是一个Python包,提供快速、灵活和富有表现力的数据结构,使关联或标记数据的使用既简单又直观。

它旨在成为Python中进行实际,真实世界数据分析的基础高级构建块。此次外还有更广泛的目标,即称为任何语言中最强大,最灵活的开源数据分析/操作工具。

适合许多不同类型的数据

  • 具有异构类型列的表格数据,如SQL表或Excel表
  • 有序和无序的时间序列数据
  • 具有行和列标签的任意矩阵数据
  • 任何其他形式的观察/统计数据集。实际上不需要将数据标记为放置在pandas数据结构中

2.Pandas中的数据结构

Pandas 中除了 Panel 数据结构,还引入了两种新的数据结构一-Series和 DataFrame ,这两种数据结构都建立在 NumPy 的基础之上。

( 1 ) Series :一维数组系列,也称序列,与 Numpy中的一维 array 类似。 二者与Python 基本的数据结构 list 也很相近。

( 2 ) DataFrame :二维的表格型数据结构。可以将DataFrame 理解为 Series 的容器。以下的内容主要以DataFrame为主。

( 3) Panel:三维 数 组,可以理解为 DataFrame 的 容器。

3.数据结构

    3.1 Series 一维数组 <==> array,list

# -*- coding: UTF-8 -*-
'''
@Author :Jason
Pandas 的数据结构:Pandas 主要有 Series(一维数组),DataFrame(二维数组),Panel(三维数组),Panel4D(四维数组),PanelND(更多维数组)
等数据结构。其中 Series 和 DataFrame 应用的最为广泛
'''
import pandas as pd
import numpy as np
#创建Series数据类型的三种方法
def createSeries():
    #1.列表创建
    list1 = [1,2,3,4,5]
    s1 = pd.Series(list1) #如果不指定索引,默认从0开始
    print(s1)
    '''
    0    1
    1    2
    2    3
    3    4
    dtype: int64
    '''

    #2.从加入所以创建Series
    list2 = np.random.randn(5) #随机五位小数
    indexList = ["a","b","c","d","e"]
    s2 = pd.Series(list2,index=indexList)
    print(s2)
    '''
    a    3.198744
    b    0.214999
    c   -0.272966
    d    0.089220
    e   -0.895139
    dtype: float64
    '''

    #3.从字典创建
    dict1 = {"a":1,"b":2,"c":3,"d":4,"e":5}
    s3 = pd.Series(dict1)
    print(s3)
    '''
    a    1
    b    2
    c    3
    d    4
    e    5
    dtype: int64
    '''
def seriesBaseOperate():
    list1 = [1,2,3,4,5]
    s1 = pd.Series(list1)
    s1.index = ["A","B","C","D","E"] #将下标12345,改为ABCDE
    print(s1)
    '''
    A    1
    B    2
    C    3
    D    4
    E    5
    dtype: int64
    '''

    list2 = np.random.randn(5)
    indexList = ["a", "b", "c", "d", "e"]
    s2 = pd.Series(list2,index=indexList)
    print(s2)
    '''
    a   -1.273575
    b   -1.074655
    c   -0.772257
    d    0.694503
    e    1.254038
    dtype: float64
    '''

    d = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
    s3 = pd.Series(d)
    s4 = s3.append(s1)  # 将s1拼接到s3,注意不能拼接单个元素
    print(s4)
    '''
    a    1
    b    2
    c    3
    d    4
    e    5
    A    1
    B    2
    C    3
    D    4
    E    5
    dtype: int64
    '''

    s4 = s4.drop("e")  # 删除索引为e的值
    s4["A"] = "JASON"  # 修改索引A的值
    print(s4["A"])  # 查值
    print(s4[0:3])  # 切片
    '''
    JASON
    a    1
    b    2
    c    3
    dtype: object
    '''

#Series运算操作
def operatingSeries():
    list1 = [1,2,3,4,5]
    s1 = pd.Series(list1)

    n = np.random.randn(5)
    indexList = ["a","b","c","d","e"]
    indexList1 = [1,2,3,4,5]
    s2 = pd.Series(n,index = indexList1)

    print(s1.add(s2))  #Series 的加法运算是按照索引计算,如果索引不同则填充为 `NaN`(空值)
    '''
    0         NaN
    1    1.392250
    2    2.856717
    3    4.037887
    4    3.496885
    5         NaN
    dtype: float64
    '''

    print(s1.sub(s2))
    '''
    0         NaN
    1    2.607750
    2    3.143283
    3    3.962113
    4    6.503115
    5         NaN
    dtype: float64
    '''

    print(s1.mul(s2))
    '''
    0         NaN
    1   -1.215499
    2   -0.429849
    3    0.151548
    4   -7.515576
    5         NaN
    dtype: float64
    '''

    print(s1.div(s2))
    '''
    0           NaN
    1     -3.290829
    2    -20.937609
    3    105.577265
    4     -3.326425
    5           NaN
    dtype: float64
    '''
    print(s1.median())  #中位数  3.0
    print(s1.max())  #    5
    print(s1.sum())  #    15


if __name__ == "__main__":
    # createSeries()
    # seriesBaseOperate()
    operatingSeries()

    3.2 DataFrame 二维数组 <===> ndarray

# -*- coding: UTF-8 -*-
'''
二维数组DataFrame <==> ndarray
'''
import pandas as pd
import numpy as np
from pandas import Series

class DF(object):
    def __init__(self):
        dates = pd.date_range("today", periods=6)  # 定义时间序列作为index
        num_arr = np.random.randn(6, 4)  # 传入nunpy的随机小数数组
        colnum = ["A", "B", "C", "D"]
        self.df1 = pd.DataFrame(data=num_arr, index=dates, columns=colnum)
        self.dataInfo = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
                    'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
                    'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
                    'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}

        labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
        self.df2 = pd.DataFrame(data=self.dataInfo, index=labels)
    def createDataFrame(self):
        print(self.df1)
        '''
                                           A         B         C         D
        2018-12-05 19:26:33.079050  1.238997  1.178291  0.682551  0.083252
        2018-12-06 19:26:33.079050 -0.682866  0.168864 -0.702818 -1.183783
        2018-12-07 19:26:33.079050 -0.042540  1.595481 -0.157319 -1.531944
        2018-12-08 19:26:33.079050 -1.397062 -0.853874 -0.365774 -0.865814
        2018-12-09 19:26:33.079050  0.997983 -0.871088  0.856143 -0.322108
        2018-12-10 19:26:33.079050  0.134739 -0.886856 -0.731986 -0.975596
        '''


        print(self.df2)
        '''
          animal  age  visits priority
        a    cat  2.5       1      yes
        b    cat  3.0       3      yes
        c  snake  0.5       2       no
        d    dog  NaN       3      yes
        e    dog  5.0       2       no
        f    cat  2.0       3       no
        g  snake  4.5       1       no
        h    cat  NaN       1      yes
        i    dog  7.0       2       no
        '''
        print(self.df2.shape)  # 属性(10,4) #10行4列

    def dataFrame(self):
        '''
        dataFrmme的各种方法
        :return: None
        '''
        # print(self.df1)
        # print(self.df2.head()) #1.head(n) 查看前几个值,默认前5
        '''
          animal  age  visits priority
        a    cat  2.5       1      yes
        b    cat  3.0       3      yes
        c  snake  0.5       2       no
        d    dog  NaN       3      yes
        e    dog  5.0       2       no
        '''
        # print(self.df2.tail(3)) #查看后3个的值
        '''
            animal  age  visits priority
        h    cat  NaN       1      yes
        i    dog  7.0       2       no
        j    dog  3.0       1       no
        '''
        # print(self.df2.columns) #2.查看列名
        '''Index(['animal', 'age', 'visits', 'priority'], dtype='object')'''
        # print(self.df2.values) #查看值
        '''
        [['cat' 2.5 1 'yes']
         ['cat' 3.0 3 'yes']
         ['snake' 0.5 2 'no']
         ['dog' nan 3 'yes']
         ['dog' 5.0 2 'no']
         ['cat' 2.0 3 'no']
         ['snake' 4.5 1 'no']
         ['cat' nan 1 'yes']
         ['dog' 7.0 2 'no']
         ['dog' 3.0 1 'no']]
        '''
        # print(self.df2.index) #查看索引
        '''
        Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], dtype='object')
        '''
        # print(self.df2.describe()) #3.查看数据统计
        '''
                    age     visits
        count  8.000000  10.000000
        mean   3.437500   1.900000
        std    2.007797   0.875595
        min    0.500000   1.000000
        25%    2.375000   1.000000
        50%    3.000000   2.000000
        '''
        # print(self.df2.T)#4.转置操作
        '''
                    a    b      c    d    e    f      g    h    i    j
        animal    cat  cat  snake  dog  dog  cat  snake  cat  dog  dog
        age       2.5    3    0.5  NaN    5    2    4.5  NaN    7    3
        visits      1    3      2    3    2    3      1    1    2    1
        priority  yes  yes     no  yes   no   no     no  yes   no   no
        '''
        # print(self.df2['age']) #5.通过标签查询
        '''
        a    2.5
        b    3.0
        c    0.5
        d    NaN
        e    5.0
        f    2.0
        g    4.5
        h    NaN
        i    7.0
        j    3.0
        Name: age, dtype: float64
        '''
        # print(self.df2.iloc[1:3]) #6.查询2,3行
        '''
            animal  age  visits priority
        b    cat  3.0       3      yes
        c  snake  0.5       2       no
        '''
        # print(self.df2.iat[1,0]) #7.按照坐标查询   2行1列的数据
        '''
        cat
        '''
        # print(self.df2.loc["f","age"])#8.按照标签和索引 f行标签为age的数据
        '''
        2.0
        '''

        #9.添加列数据(先创建一个Series,然后添加)
        df3 = self.df2
        num = Series([0,1,2,3,4,5,6,7,8,9],index=df3.index)
        df3['No.'] = num #添加以No.为列名的新数据
        # print(df3)
        '''
          animal  age  visits priority  No.
        a    cat  2.5       1      yes    0
        b    cat  3.0       3      yes    1
        c  snake  0.5       2       no    2
        d    dog  NaN       3      yes    3
        e    dog  5.0       2       no    4
        f    cat  2.0       3       no    5
        g  snake  4.5       1       no    6
        h    cat  NaN       1      yes    7
        i    dog  7.0       2       no    8
        j    dog  3.0       1       no    9
        '''

        #10.删除数据
        df22  = self.df2
        df23 = df22.drop("age",axis=1) #delete table where yid = "age"
        # print(df23)
        '''
              nimal  visits priority  No.
        a    cat       1      yes    0
        b    cat       3      yes    1
        c  snake       2       no    2
        d    dog       3      yes    3
        e    dog       2       no    4
        f    cat       3       no    5
        g  snake       1       no    6
        h    cat       1      yes    7
        i    dog       2       no    8
        j    dog       1       no    9
        '''
        df24 = df22.drop(["age","No."],axis=1)#相当于delete table where yid = "age" or yid = "No."
        # print(df24)
        '''
          animal  visits priority
        a    cat       1      yes
        b    cat       3      yes
        c  snake       2       no
        d    dog       3      yes
        e    dog       2       no
        f    cat       3       no
        g  snake       1       no
        h    cat       1      yes
        i    dog       2       no
        j    dog       1       no
        '''
        df25 = df22.dropna(how="any") #how参数any,只要有缺失值就删除
        # print(df25)
        '''
            animal  age  visits priority  No.
        a    cat  2.5       1      yes    0
        b    cat  3.0       3      yes    1
        c  snake  0.5       2       no    2
        e    dog  5.0       2       no    4
        f    cat  2.0       3       no    5
        g  snake  4.5       1       no    6
        i    dog  7.0       2       no    8
        j    dog  3.0       1       no    9
        '''
        #11.缺失值处理(填充)
        df4 = df3.fillna(value=3) #值为Nan地方填充为3,可以df3对比,返回值,不能直接改变df3
        # print(df4)
        '''
           animal  age  visits priority  No.
        a    cat  2.5       1      yes    0
        b    cat  3.0       3      yes    1
        c  snake  0.5       2       no    2
        d    dog  3.0       3      yes    3
        e    dog  5.0       2       no    4
        f    cat  2.0       3       no    5
        g  snake  4.5       1       no    6
        h    cat  3.0       1      yes    7
        '''

        #12.条件查找
        # print(self.df2[self.df2["age"] < 3]) #注意Nan不参与计算
        '''
            animal  age  visits priority  No.
        a    cat  2.5       1      yes    0
        c  snake  0.5       2       no    2
        f    cat  2.0       3       no    5
        '''
        # print(self.df2[(self.df2["animal"] == "cat") & (self.df2["age"]> 2)])
        '''
          animal  age  visits priority  No.
        a    cat  2.5       1      yes    0
        b    cat  3.0       3      yes    1
        '''
        # print(self.df2[self.df2["animal"].isin(["cat","dog"])]) #animal索引中包含cat,dog的
        '''
          animal  age  visits priority  No.
        a    cat  2.5       1      yes    0
        b    cat  3.0       3      yes    1
        d    dog  NaN       3      yes    3
        e    dog  5.0       2       no    4
        f    cat  2.0       3       no    5
        h    cat  NaN       1      yes    7
        i    dog  7.0       2       no    8
        j    dog  3.0       1       no    9
        '''
        #13.行列索引切片
        # print(self.df2.iloc[2:4,1:3])  #2-4行,1-3列的数据
        '''
           age  visits
        c  0.5       2
        d  NaN       3
        '''

        #14.排序操作
        # print(self.df2.sort_values(by=["age","visits"],ascending=[False,True]))
        #根据age降序,visits升序排列,根据sql经验会报错,这里竟然没
        '''
          animal  age  visits priority  No.
        i    dog  7.0       2       no    8
        e    dog  5.0       2       no    4
        g  snake  4.5       1       no    6
        j    dog  3.0       1       no    9
        b    cat  3.0       3      yes    1
        a    cat  2.5       1      yes    0
        f    cat  2.0       3       no    5
        c  snake  0.5       2       no    2
        h    cat  NaN       1      yes    7
        d    dog  NaN       3      yes    3
        '''

        #15.DataFrame 多值替换
        # print(self.df2["priority"].map({"yes":1,"no":0})) #将yes替换为1,no替换为0
        '''
        a    1
        b    1
        c    2
        d    1
        e    2
        f    2
        g    2
        h    1
        i    2
        j    2
        Name: priority, dtype: int64
        '''
        #16.分组操作
        print(self.df2.groupby("animal").sum())
        '''
                 age  visits  No.
        animal                   
        cat      7.5       8   13
        dog     15.0       8   24
        snake    5.0       3    8
        '''
if __name__ == "__main__":
    df = DF()
    # df.createDataFrame()
    df.dataFrame()

参照:《基于Python的大数据分析基础及实战》

2018-03-04 13:25:59 qq_17119267 阅读数 139
  • Python基础

    Python 以其简洁、优雅、高效的特点,成为目前流行的4大主流开发语言之一,其应用广泛,易学易用,让很多人爱不释手。本套课程为初学者量身打造,是你入门 Python 的必修课程。这一部分内容涵盖了Python基础的知识点,包括Python的基础语法,比如变量,字符编码等,数据类型以及if else,for循环等流程控制语句,内容简单却十分关键,无论是数据类型还是控制语句都是在以后的Python学习无论方向都会反复大量应用的。 此课程特别适合之前完全无任何开发经验的小白白学习! Python除了是人工智能领域第一语言之外,其实还广泛的应用于WEB开发、云计算、金融分析、自动化运维、自动化测试、爬虫、大数据分析等领域,生态圈极为丰富和活跃。它强大的模块库大大的提高了开发者的开发效率,简洁明朗的语法使写代码如写诗一样优雅顺畅,极大降低了编程的学习门槛。可以不谦虚的说,Python是唯一一门无论是开发老司机还是小白白都一致称赞的编程语言。 不论你是什么背景出身,如果对编程感兴趣,从Python入手吧,Python是检测你是否适合做程序员的好的语言,如果练Python都学不会,哈哈,那你可以放弃这个职业啦!

    14317 人正在学习 去看看 李杰

Python-mysql数据库基础

本节知识点

知识点一: MySQL 基本结构

知识点二: 库、表操作

知识点三: 数据 CRUD 操作

知识点四: Python 操作 MySQL

part one :mysql简介

Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口。

Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库:

  • GadFly
  • mSQL
  • MySQL
  • PostgreSQL
  • Microsoft SQL Server 2000
  • Informix
  • Interbase
  • Oracle
  • Sybase

你可以访问Python数据库接口及API查看详细的支持数据库列表。

不同的数据库你需要下载不同的DB API模块,例如你需要访问Oracle数据库和Mysql数据,你需要下载Oracle和MySQL数据库模块。

DB-API 是一个规范. 它定义了一系列必须的对象和数据库存取方式, 以便为各种各样的底层数据库系统和多种多样的数据库接口程序提供一致的访问接口 。

Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库。

Python DB-API使用流程:

  • 引入 API 模块。
  • 获取与数据库的连接。
  • 执行SQL语句和存储过程。
  • 关闭数据库连接。本文我们为大家介绍 Python3 使用 PyMySQL 连接数据库,并实现简单的增删改查。

什么是 PyMySQL?

PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。

PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。

关于MySQL 的一些基本问题

问题一: MySQL是数据库嘛 ?

  • 不是数据库,数据库管理软件

问题二: MySQL是如何来组织数据 ?

  • MySQL 组织数据的基本形式
    • 截图20180304115355

问题三: 如何进入MySQL数据库 ?

  • 进入与退出 数据库

    • $ mysql –uusername -ppassword

    图片zzzzzz1

    • mysql> exit

问题四: 其他基本注意事项

  • 语句结束符: 每个语句都以 ; 或 \G 结束
  • 大小写: 不严格区分大小写
  • 类型: 强制数据类型、任何数据都有自己的类型
  • 逗号: 最后一列不需要逗号

part two:库、表级操作

库、表级操作 问题引入

问题一:如何管理 MySQL 中的数据库 ?

问题二:如何管理数据表 ?

问题三:可以对数据表加一些约束嘛 ?

库级 管理语句
  • 显示所有库: SHOW DATABASES;
  • 创建库: CREATE DATABASE db_name;
  • 显示库创建信息: SHOW CREATE DATABASE db_name;
  • 删除库: DROP DATABASE db_name;
  • 切换当前数据库: USE db_name;
表级 管理语句
  • 显示所有表: SHOW TABLES
  • 创建表: CREATE TABLE tb_name(columns);
  • 显示表创建信息: SHOW CREATE TABLE tb_name;
  • 删除表: DROP TABLE tb_name;
常用约束
  • 整数: INT / BOOL
  • 实数: DOUBLE / DECIMAL
  • 文本: CHAR / VARCHAR
  • 时间: DATE / DATETIME
  • 非空:NOT NULL(主键: PRIMARY
  • 默认: DEFAULT(主键: PRIMARY
  • 唯一: UNIQUE(主键: PRIMARY
  • 参照(外键): FOREIGN KEY REFERENCES

数据库库命令基本操作:

# 显示所有数据库
SHOW DATABASES;
# 创建一个叫做 python3 的数据库
CREATE DATABASE python3;
# 查看 python3 这个数据库 的创建信息
SHOW CREATE DATABASE python3;
# 删除 python3 这个数据库
DROP DATABASE python3;
# 切换到 python3 这个数据库
USE python3;

# 显示当前数据库中的所有表
SHOW TABLES;
# 创建一个 学生表
CREATE TABLE students(
  id INT,    # id字段 是一个整数字段,通常每张表都会有一个
  number CHAR(9),    # 学号,肯定是9位,例如:201803001
  name VARCHAR(20),    # 名字,最大长度20
  age BOOL,    # 年龄:非01
  birth DATE    # 生日: 日期
);
# 查看 students 这个数据表 的创建信息
SHOW CREATE TABLE students;
# 删除 students 这个数据表
DROP TABLE students;

part three :数据级 CRUD操作

注:(Create 创建 增加Read 读取 查询Update 更新 修改Delete 删除 删除)

问题一: 如何查看表中的数据 ?

  • R(Read) —SELECT FROM WHERE
    • 指定列查询:SELECT col_names FROM tb_name;
    • 全列查询: SELECT * FROM tb_name;
    • 带条件的查询: SELECT col_names FROM tb_name WHERE conditions;

问题二: 如何向表中插入数据 ?

  • C(Create)—INSERT INTO VALUES
    • 指定列插入: INSERT INTO tb_name(col_names) VALUES (col_values);
    • 全列插入: INSERT INTO tb_name VALUES (all_values);
    • 多行插入: INSERT INTO tb_name(col_names) VALUES (value_1), (value_2), …;

问题三: 如何修改表中的数据 ?

  • U(Update) —UPDATE SET WHERE
    • UPDATE tb_name SET field_1=value_1, field_2=value_2,…WHERE a_field = a_value;

问题四: 如何删除表中的数据 ?

  • D(Delete) —DELETE FROM WHERE
    • DELETE FROM tb_name WHERE a_field = a_value;

数据库表命令操作:

# 向 students 这张表中插入数据
# 向 students 的 指定列 插入数据
INSERT INTO students(id, name, age, birth) VALUES (1, 'Tuple', 18, '2000-01-01');
# 向 students 的 所有列插入数据
INSERT INTO students VALUES (2, '201803001', 'Luck', 18, '2000-01-02');
# 向 students 的 一次性插入多条数据
INSERT INTO students VALUES (2, '201803002', 'Xiaopo', 18, '2000-01-03'),(3, '201803003', 'Budong', 18, '2000-01-04');

# 查询 students 表中的数据
# 查询 students 的 指定列的数据
SELECT name, age, birth FROM students;
# 查询 students 的 查询所有列数据
SELECT * FROM students;
# 查询 students 中 关于 Tuple的数据
SELECT * FROM students WHERE name='Tuple';
# 将 Tuple 的学号改为 201803004
UPDATE students SET number='201803004' WHERE name='Tuple';
# 删除 Tuple 这条数据
DELETE FROM students WHERE name='Tuple';

part four :Python操作MySQL

DB-API 问题引入

问题一: Python能直接操作MySQL嘛 ?

  • Python不能直接操作MySQL,是通过pymysql连接器实现

    这里写图片描述

    问题二: 大家所说的 DB-API 是什么 ?

  • Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口。

    • 连接接口: pymysql.connect(**dbconfig)

    • 关闭接口: cnn.close()

    • 游标接口: cnn.cursor()

    • 关闭游标: cur.close()

    • 执行接口: cur.execute(sql)

    • 结果集接口: cur.fetchall()

    • 提交接口:conn.commit()

    • 回滚接口:conn.rollback()

    (连接是不能操作数据库的需要用连接生成游标来从操作)

问题三: 使用 DB-API 时有什么需要注意的嘛 ?

  • 注意点一: 和文件一样,别忘了关闭 游标与连接
  • 注意点二: 在pymysql中执行SQL不需要加 ;
  • 注意点三: execute 执行完后不是直接得到结果集而需要你主动去获取
  • 注意点四: 在pymysql中执行玩数据库操作后需要 执行commit()提交数据 ;
思维路线

这里写图片描述

数据库连接

连接数据库前,请先确认以下事项:

  • 您已经创建了数据库 TESTDB.
  • 在TESTDB数据库中您已经创建了表 EMPLOYEE
  • EMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。
  • 连接数据库TESTDB使用的用户名为 “testuser” ,密码为 “test123”,你可以可以自己设定或者直接使用root用户名及其密码,Mysql数据库用户授权请使用Grant命令。
  • 在你的机子上已经安装了 Python MySQLdb 模块。
  • 如果您对sql语句不熟悉,可以访问我们的 SQL基础教程

实例:

以下实例链接 Mysql 的 TESTDB 数据库:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用 execute()  方法执行 SQL 查询 
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法获取单条数据.
data = cursor.fetchone()

print ("Database version : %s " % data)

# 关闭数据库连接
db.close()

输出结果:

Database version : 5.5.20-log
创建数据库表

如果数据库连接存在我们可以使用execute()方法来为数据库创建表,如下所示创建表EMPLOYEE:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用 execute() 方法执行 SQL,如果表存在则删除
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")

# 使用预处理语句创建表
sql = """CREATE TABLE EMPLOYEE (
         FIRST_NAME  CHAR(20) NOT NULL,
         LAST_NAME  CHAR(20),
         AGE INT,  
         SEX CHAR(1),
         INCOME FLOAT )"""

cursor.execute(sql)

# 关闭数据库连接
db.close()
数据库插入操作

以下实例使用执行 SQL INSERT 语句向表 EMPLOYEE 插入记录:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
       LAST_NAME, AGE, SEX, INCOME) \
       VALUES ('%s', '%s', '%d', '%c', '%d' )" % \
       ('Mac', 'Mohan', 20, 'M', 2000)
try:
   # 执行sql语句
   cursor.execute(sql)
   # 执行sql语句
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()

以上例子也可以写成如下形式:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
       LAST_NAME, AGE, SEX, INCOME) \
       VALUES ('%s', '%s', '%d', '%c', '%d' )" % \
       ('Mac', 'Mohan', 20, 'M', 2000)
try:
   # 执行sql语句
   cursor.execute(sql)
   # 执行sql语句
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()

以下代码使用变量向SQL语句中传递参数:

..................................
user_id = "test123"
password = "password"

con.execute('insert into Login values("%s", "%s")' % \
             (user_id, password))
..................................
数据库查询操作

Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据。

  • fetchone(): 该方法获取下一个查询结果集。结果集是一个对象
  • fetchall(): 接收全部的返回结果行.
  • rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。

实例:

查询EMPLOYEE表中salary(工资)字段大于1000的所有数据:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
       WHERE INCOME > '%d'" % (1000)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 获取所有记录列表
   results = cursor.fetchall()
   for row in results:
      fname = row[0]
      lname = row[1]
      age = row[2]
      sex = row[3]
      income = row[4]
       # 打印结果
      print ("fname=%s,lname=%s,age=%d,sex=%s,income=%d" % \
             (fname, lname, age, sex, income ))
except:
   print ("Error: unable to fetch data")

# 关闭数据库连接
db.close()

执行结果如下:

fname=Mac, lname=Mohan, age=20, sex=M, income=2000
数据库更新操作

更新操作用于更新数据表的的数据,以下实例将 TESTDB表中的 SEX 字段全部修改为 ‘M’,AGE 字段递增1:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = '%c'" % ('M')
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()
删除操作

删除操作用于删除数据表中的数据,以下实例演示了删除数据表 EMPLOYEE 中 AGE 大于 20 的所有数据:

#!/usr/bin/python3

import pymysql

# 打开数据库连接
db = pymysql.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交修改
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭连接
db.close()
执行事务

事务机制可以确保数据一致性。

事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。

  • 原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
  • 一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
  • 隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
  • 持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

Python DB API 2.0 的事务提供了两个方法 commit 或 rollback。

实例:

# SQL删除记录语句
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 向数据库提交
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

对于支持事务的数据库, 在Python数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。

commit()方法游标的所有更新操作,rollback()方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。

错误处理

DB API中定义了一些数据库操作的错误及异常,下表列出了这些错误和异常:

异常 描述
Warning 当有严重警告时触发,例如插入数据是被截断等等。必须是 StandardError 的子类。
Error 警告以外所有其他错误类。必须是 StandardError 的子类。
InterfaceError 当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。 必须是Error的子类。
DatabaseError 和数据库有关的错误发生时触发。 必须是Error的子类。
DataError 当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。 必须是DatabaseError的子类。
OperationalError 指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是DatabaseError的子类。
IntegrityError 完整性相关的错误,例如外键检查失败等。必须是DatabaseError子类。
InternalError 数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。 必须是DatabaseError子类。
ProgrammingError 程序错误,例如数据表(table)没找到或已存在、SQL语句语法错误、 参数数量错误等等。必须是DatabaseError的子类。
NotSupportedError 不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上 使用.rollback()函数,然而数据库并不支持事务或者事务已关闭。 必须是DatabaseError的子类。

本机测试数据库连接实例1:

import pymysql
db_config = {
    'host': '127.0.0.1',
    'user': 'root',
    'password': 'qwe123',
    'db': 'python3',
    'charset': 'utf8',
}
table_teacher = "CREATE TABLE teacher(id INT,number CHAR(9),name VARCHAR(20),age BOOL,birth DATE);"
use_python3 = 'USE python3;'
show_table = 'SHOW TABLES;'
insert_data ="INSERT INTO teacher VALUES (2, '201803002', 'Xiaopo', 18, '2000-01-03'),(3, '201803003', 'Budong', 18, '2000-01-04');"
find_data = 'SELECT * FROM teacher;'
conn = pymysql.connect(**db_config)
try:
    cur = conn.cursor()
    #rv = cur.execute(insert_data)
    rv = cur.execute(find_data)
    res = cur.fetchall()
    print(type(rv),type(res))
    for entry in res:
        print(entry)
except Exception as e :
    print('执行过程中发生了异常',e)
    conn.rollback()
finally:
    conn.commit()
    cur.close()
    conn.close()

输出结果:

<class 'int'> <class 'tuple'>
(2, '201803002', 'Bob', 18, datetime.date(2000, 1, 3))
(3, '201803003', 'Alice', 18, datetime.date(2000, 1, 4))

2019-05-27 19:34:51 Charein 阅读数 1492
  • Python基础

    Python 以其简洁、优雅、高效的特点,成为目前流行的4大主流开发语言之一,其应用广泛,易学易用,让很多人爱不释手。本套课程为初学者量身打造,是你入门 Python 的必修课程。这一部分内容涵盖了Python基础的知识点,包括Python的基础语法,比如变量,字符编码等,数据类型以及if else,for循环等流程控制语句,内容简单却十分关键,无论是数据类型还是控制语句都是在以后的Python学习无论方向都会反复大量应用的。 此课程特别适合之前完全无任何开发经验的小白白学习! Python除了是人工智能领域第一语言之外,其实还广泛的应用于WEB开发、云计算、金融分析、自动化运维、自动化测试、爬虫、大数据分析等领域,生态圈极为丰富和活跃。它强大的模块库大大的提高了开发者的开发效率,简洁明朗的语法使写代码如写诗一样优雅顺畅,极大降低了编程的学习门槛。可以不谦虚的说,Python是唯一一门无论是开发老司机还是小白白都一致称赞的编程语言。 不论你是什么背景出身,如果对编程感兴趣,从Python入手吧,Python是检测你是否适合做程序员的好的语言,如果练Python都学不会,哈哈,那你可以放弃这个职业啦!

    14317 人正在学习 去看看 李杰

本书特色

想深入应用手中的数据?还是想在上千份文件中重复同样的分析过程?没有编程经验的非程序员们如何能在最短的时间内学会用当今炙手可热的Python语言进行数据分析?

来自Facebook的数据专家Clinton Brownley可以帮您解决上述问题。在他的这本书里,读者将能掌握基本Python编程方法,学会编写出处理电子表格和数据库中的数据的脚本,并了解使用Python模块来解析文件、分组数据和生成统计量的方法。

● 学习基础语法,创建并运行自己的Python脚本
● 读取和解析CSV文件
● 读取多个Excel工作表和工作簿
● 执行数据库操作
● 搜索特定记录、分组数据和解析文本文件
● 建立统计图并绘图
● 生成描述性统计量并估计回归模型和分类模型
● 在Windows和Mac环境下按计划自动运行脚本

“这本书对于那些使用数据的Python新手来说,是非常有用的学习资源。它的教学风格和附带的例子会帮助用户尽快熟悉Python语言、编程环境和Python生态系统中最常用的几个软件包。”

——Wes McKinney,pandas库之父

目录

版权声明 阅读
O’Reilly Media, Inc. 介绍
献词
前言
第 1 章 Python 基础
第 2 章 CSV 文件
第 3 章 Excel 文件
第 4 章 数据库
第 5 章 应用程序
第 6 章 图与图表
第 7 章 描述性统计与建模
第 8 章 按计划自动运行脚本
第 9 章 从这里启航
附录 A 下载指南
附录 B 练习答案
作者介绍 阅读
封面介绍

下载

https://pan.baidu.com/s/13khO1kUc5QdfTevqXgXEzA

python的基本数据类型

博文 来自: qq_31561851

Python基础

阅读数 368

Python基础 数据类型

博文 来自: weixin_44481489
没有更多推荐了,返回首页