zoukankan      html  css  js  c++  java
  • numpy、pandas

    numpy:
    仨属性:ndim-维度个数;shape-维度大小;dtype-数据类型。
    numpy和pandas各def的axis缺省为0,作用于列,除DataFrame的.sort_index()和.dropna()外。
     
    import numpy as np
     
    相同值=np.ones((3,5),int)  #同类:np.zeros(),np.empty();首参shape用()或[]均可
    转换类型=相同值.astype(np.float64) #转换行列=相同值.transpose()
    随机整数=np.random.randint(-30,70,(5,6))  #size参数用()或[]如[5,6]都行
    随机带小数=np.random.uniform(-5,9,(5,6)) #返回二维[[][]…]
    带2=np.random.uniform(9,size=6)  #一维[],6个<9的带小数;参数无min时size=不能省
    随机纯小数=np.random.rand(5,6)  #标准正态分布=np.random.randn(5,6)
    自然数=np.arange(10,40).reshape((5,6))  #1维np.arange()转2维np.array(),用.reshape((行,列))
    自2=np.arange(10,40);np.random.shuffle(自2);自2=自2.reshape((5,6))  #shuffle洗牌不了多维
    多种类=np.array([range(0,5)]*4+[list('abcde')]+[range(2,7)])   #range、[]各再套个[]就能用+
    去重并排序=np.unique(多种类)    #返回无重复元素的一维[],像是OrderedSet
     
    索引与切片=自然数[:,3:]  #首行用[0],首列用[:,0];自然数[2,3]等价于自然数[2][3]
    元素判断1=np.all(随机整数<10)    #反义词np.any()
    元素判断2=np.where(随机整数>0,'正数','负数')
    元素计算=np.ceil(随机带小数) #地板floor(),四舍五入rint(),绝对值abs(),非数值isnan()
    元素累计=np.cumsum(自然数,1)  #二维可用axis,为0累下为1累右,无返1维;累乘cumprod()
    #只写首参统计全维,返回1个int;2维若用了2参axis(列0行1)则按各列或各行统计,返回[]
    矩阵统计=np.sum(自然数,0)   #mean()、max()、min的索引argmin()、标准差std()、var()
     
    多矩阵运算1=np.multiply(自然数,自2)   #各矩阵的形状要相同;np.divide(*,*)
    多矩阵运算2=自然数+自然数    #自然数-5;自然数*2;1/自然数
    #多个条件用&或|连接,而非Python的and或or;每个条件都用()括起来
    条件索引=随机整数[(自然数>=20) & (自然数%2==0)]   #同上,各矩阵的行&列数要一致
     
    ****************************************分割线****************************************
    pandasのSeries和DataFrame:
     
    Series:
     
    import pandas as pd
    sr=pd.Series(range(10,20),index=list(string.ascii_letters[:10]))    #{2016:8,2017:5}
    sr.name='temp'  #sr.index.name='年份'
    单索引=sr[2]   #或sr['c'];DataFrame中:某列用df['str']或df.str,某行为df.iloc[[int],]
    切片=sr[2:5]  #按标签切时如sr['c':'e'],包含终止索引
    不连续索引=sr[[0,4,6]]   #或sr[['a','e','g']],注意是两对[ ]
    首或尾=sr.tail(6)  #.head()或.tail()内若没写数字,则默认取5条记录
    sr[0:7].values[1]=666   #.values属性的值可变,索引列.index不可单个变,类似[]与()
    元素计算=sr**2  #在元素层面自定义的map方法:sr.map(lambda m:'%0.4d' %(m**2))
    sr[sr<15]=-sr*3+7  #对布尔索引为True的那些元素做各种运算
    **********************分割线**********************
    DataFrame:
     
    三种索引——int型序号索引iloc、str型标签索引loc、混合索引ix。
    序号切片行时如df.iloc[0:3,],可简写为df[0:3];标签loc的简写相反,只索引列有3种场景,非切片列的那俩即单列&不连续列的索引都可简写;另外切片时,df.loc[]和df.ix[]若用了标签,则行&列都包含终止。
    import numpy as np,pandas as pd,string
     
    data=np.arange(11,41).reshape((6,5))
    index=pd.date_range('20170101',periods=6,freq='5D').strftime('%x')
    columns=list(string.ascii_uppercase[:5])
    df=pd.DataFrame(data,index,columns)
    *******分割线*******
    索引:
     
    单行索引=df.iloc[[2],]   #若里面没套[ ],则是纵向输出此行
    不连续的行索引=df.iloc[[0,2,3],]
    行切片=df[0:4] #df.iloc[0:4,]的简写

    单列索引=df['B']    #df.loc[:,'B']的简写
    不连续列的索引=df[['A','D']]   #df.loc[:,['A','D']]的简写
    列切片=df.loc[:,'A':'D']   #标签索引的切片竟包含终止,位置索引的切片正常不含终止
     
    行列索引1=df.iloc[[0,1,3],1:4]  #除iloc切片行或loc非切片列外,其他场景均要写.iloc或.loc
    行列索引2=df.ix[0:2,['A','E']]  #混合索引df.ix[*,*]是否含终止,取决于1参或2参是否用了标签
    *******分割线*******
    计算:
     
    df['W']=df.E+5  #del(df['B']),被增、删的字段都用df['key'],不能用简写的df.key
    df['m']=list('qwerty');df['m']=df['m'].str.upper()
    多值替换为一值=df.replace([20,30,'Y'],8)
    多值替换为同量=df.replace([11,22,'Q'],[9,9,6])
     
    统计=df.describe()    #数值型的那些列的8行统计信息
    按值排序=df.sort_values('E',ascending=False)  #若是按某行的值排序,则加axis=1
    标签排序=df.sort_index(axis=1)   #这次例外了,axis缺省的0值作用于行标签
    元素计算=df.copy()*3;元素计算[df<26]=-df+55  #对布尔索引为True的那些元素做各种运算
    元素计算の内置函数=df.cumsum(axis=1,skipna=False)  #max、mean、median、cumprod…
    自定义=df.applymap(lambda m:'%0.5d' %(-m**2 if len(set(str(m**2)))<3 else m*10))
    df['F']=df['C'].map(lambda m:m*2)   #map方法的范围窄,只用于Series对象
    *******分割线*******
    去重:
    data2=np.array([range(0,5)]*3+[list('abcde')]+[range(2,7)]+[list('61834')])
    df2=pd.DataFrame(data2,index,columns)
    判断重复=df2.duplicated()   #首次出现为False,再现为True,默认判断整行
    字段B和E的值同时再现则删除=df2.drop_duplicates(['B','E'])
     
    数据缺失为空:
    df3=pd.DataFrame([list(range(3)),[1,2,np.nan],[8,np.nan,5],list('qwe')])
    是否存在空数据=df3.isnull()
    填充缺失=df3.fillna(100)
    有缺失则丢弃整条=df3.dropna(1)  #axis默认的0删的是有缺失的整行,不再作用于列
    df3.dropna(1,inplace=True)  #罕见的作用于自身,返回None
    指定丢弃哪行哪列=df.drop(columns=['B','E']) #labels+axis的0是丢弃索引行
     
    对齐运算:add,sub,mul,div用fill_value填充对方的缺位,都缺为NaN;运算符+-*/无填充
    dfX=pd.DataFrame(list('5678'),dtype=np.int)
    dfY=pd.DataFrame(np.ones([2,3],np.int))
    对齐运算=dfX.add(dfY,fill_value=6)
    *******分割线*******
    DataFrame↔Series:
    sr=df.stack()   #DataFrame→Series,columns列标转为了内层index
    df1=sr.unstack(0).reindex(list('DBAEC'))  #…按行标自排;0转外层index为列标,同df.transpose()
    注:Series有内外两层index才能用unstack()。而正常的单index的Series转为DataFrame:sr.to_frame().T或pd.DataFrame(sr).transpose()。.T是.transpose()的简写版。
     
    双层索引:
    df4=pd.DataFrame(data,index=pd.MultiIndex.from_product([list('py'),list('618')]))
    根据索引的级别统计=df4.sum(level=1)  #axis默认的0上下相加,level默认的0按外层统计
    行的内层标签降序后再索引行外层标签p=df4.sort_index(0,1,False).loc['p',]  #p后有,才是行标签
    索引行内层=df4.swaplevel().loc['8']  #无法索引内层,交换至外层才行,8是标签非序号,故套''
    *******分割线*******
    矩阵拼接:
     
    merge:以某些列标为外键,左右拼接俩矩阵;how默认交集,另有outer,left,right
    data5=np.arange(13,33).reshape((4,5))
    df5=pd.DataFrame(data5,range(15,31,5),list('CDEST'))
    左右连接1=pd.merge(df,df5,'outer',['D','E'],suffixes=(':左',':右'))
    左右连接2=pd.merge(df,df5,'right',left_on='C',right_index=True,suffixes=(':L',':R'))
    print(df,df5,左右连接2,sep=' ')
     
    concatenate:无所谓外键,首参中的矩阵数≥2;pd中各矩阵的行&列数可不等,np不行
    concatのnp=np.concatenate([data,data5])  #同列数可上下合并,同行数可用左右合的axis=1
    concatのpd=pd.concat([df,df5],1,'inner')   #丢弃有NaN的行;默认的0+outer为上下贪婪
    *******分割线*******
    #单列即Series才有.value_counts()频次统计,降序输出,默认False为频次,频率用True
    某列各值的频率的倒数3名并保留2位小数=df['E'].value_counts(True).sort_values()[:3].round(2)
     
    数字列按某些列值如[df['H'].dtypes,list('中美')],分组聚合并降序,str列只有数量.size()
    应用多个聚合:.agg(['describe','size',自定义函数]);行&列数一致:.transform([np.sum,lambda df:df-df.mean()])
    import matplotlib.pyplot as plt
    df['G']=list('分分分分组组');df['H']=list('甲乙甲乙丙甲')
    r=df['E'].groupby([df['G'],df['H']]).mean().round(1).sort_values(0,False)
    r.to_csv('E:/666.csv',encoding='utf-8-sig',mode='a+')
    r.iloc[:10].plot.bar(rot=0)    #可视化top10
    plt.rcParams['font.sans-serif']=['simhei'];plt.show()
     
    透视表:
    values中多个int字段,不同的值汇总依据:{'x':len,'y':[numpy.mean,numpy.sum]};len计数
     
    df=pd.read_excel('F:/学生信息.xlsx',0,dtype=np.str)  #学号11位+,读入为文本格式
    table=pd.pivot_table(df,['学号',],['教学点','班级'],['性别','专业'],[len,np.min],0,True)
    query=table.query("教学点==['山南','林芝']")   #仅行标签能用query
    print(query)
    table.to_excel('学籍信息.xlsx')    #to_csv则外层index无分组效果
    ****************************************分割线****************************************
    把矩阵顺时针旋转90°:
     
    import numpy as np,pandas as pd
     
    matrix=np.arange(1,31).reshape((5,6))
    matrix=np.rot90(matrix,1,(1,0))    #顺时针转90°;3参默认的(0,1)是逆时针,得转3次
    matrix=pd.DataFrame(matrix).applymap(lambda x:'%0.2d' %x)
     
    print(matrix)
    *******分割线*******
    不用numpy和pandas:
     
    def rotate_matrix(row,column):
        #生成一个row行column列的自然数矩阵
        matrix = [[format(y+x*column,'02') for y in range(1, column + 1)] for x in range(row)]
        [print('   '.join(x)) for x in matrix]
        print('*'*20,'分割线','*'*20,sep='')
        [print('   '.join(x)) for x in zip(*matrix[::-1])]
     
    rotate_matrix(7,3)
    ****************************************分割线****************************************
    Egの网页表格导出为本地表格:
    import pandas as pd,requests
     
    for page in range(1,10):
        url=f'http://www.xicidaili.com/wt/{page}'
        html=requests.get(url,headers={'User-Agent':'Mozilla/5.0 Chrome/64'}).text
        df=pd.read_html(html)[0].iloc[1:,[1,2,4,5]]  #首张表的不含标题行的某些列
        df.to_csv('代理.csv',header=False,index=False,mode='a+',encoding='utf-8-sig')
    **********************分割线**********************
    Egの捞月狗LOL的皮肤分析:
     
    1、爬皮肤数据.py
     
    import requests,re
    from fake_useragent import UserAgent as ua
    from pandas import DataFrame as df
     
    url='http://www.laoyuegou.com/x/zh-cn/lol/lol/godrank.html?region=cn&area=1'
    x='.{1,600}?';y='([一-龥]+)'
    pattern=re.compile(f'item1">(#d+){x}server">{y}{x}em>(d+){x}span>(d+){x}span
    >(d+){x}age">({x}%){x}score/({x}).png{x}dan">({x})<{x}"{y}"{x}"{y}"{x}"{y}"', re.S)
     
    def downLoad():
        r=requests.get(url,headers={'User-Agent':'Mozilla/5.0 Chrome/64 Safari/537'}).text
        area=re.findall('cn-li.*?(http.*?)".*?([一-龥]{2,9})',r,re.S)
        for region in area:
            players=[]
            for page in range(1,6):
                r=requests.get(region[0]+f'&page={page}',headers={'User-Agent':ua().random})
                print(f'下载{region[1]}战区的第{page}页')
                players.extend(pattern.findall(r.text))
            df(players).to_csv('LOL.csv',header=False,index=False,mode='a+',encoding='utf-8-sig')
     
    #downLoad()
    *******分割线*******
    2、作图分析
     
    import pandas as pd,matplotlib.pyplot as plt
     
    #%matplotlib inline  #IPython环境下绘图时,使图片内嵌在交互窗口,而非弹出
    plt.rcParams['font.sans-serif']=['SimHei'];plt.rcParams['axes.unicode_minus']=False
    plt.style.use('ggplot') #风格设为仿R语言的ggplot库
    plt.rcParams['axes.labelsize']=20  #轴标题的字体尺寸
    plt.rcParams['xtick.labelsize']=9;plt.rcParams['ytick.labelsize']=9  #轴刻度的字体尺寸
    plt.rcParams['legend.fontsize']=12;plt.rcParams['figure.figsize']=[15,6]
     
    #pd.read_*:首参若为路径str则不能有中文,用open('路径str',encoding='*')可以有
    df=pd.read_csv('E:/py/LOL.csv',encoding='utf8')
    #pd.DataFrame().iterrows():各(序号,Series)组成的generator
    #for row in df.iterrows():print(row[1][0])  #row[1]是Series对象,纵向显示各行记录
    #print(df.describe())
    #df['位置'].value_counts().drop('--').plot(kind='bar',rot=45,color='r')  #图表,轴坐标斜度,颜色
    pd.concat([df[f'本命英雄{x}'] for x in range(1,4)]).value_counts()[:10].plot(kind='barh',rot=0)
    plt.show()    #玩家最常用的前10个本命英雄,其频次的水平条形图
    ****************************************分割线****************************************
    matplotlib:
     
    plt.savefig()写在.show()之前或不写.show(),可设置保存时裁白边。
    裁白边前的分辨率plt.figure(),写在.plot()等绘图法之前,值为dpi*figsize中的(宽,高)英寸。
    主体颜色c、散点的轮廓色edgecolors、俩折线图间的填充色facecolor:①'r、g、b或完整单词或无色的none';②各值在[0,1]间的(r,g,b);③scatter散点图的4参为list,值越大则红绿蓝越深,有3类:列表=range(len(x或y))则先浅后深、=y则y↑越深,=x则x→越深。
     
    如下几例的共同代码:
    from datetime import datetime as dt
    from numpy.random import randint,choice,shuffle
     
    import numpy as np,pandas as pd,matplotlib.pyplot as plt
    plt.rcParams['font.sans-serif']=['SimHei'];plt.rcParams['axes.unicode_minus']=False
    plt.figure(dpi=160,figsize=(8,5))  #参数也可写在plt.savefig(**kwargs)里
    #plt.xkcd()  #漫画风格,不支持中文标题;plt.rcdefaults()重置为正常风格
    ***************分割线***************
    #字体尺寸:图表标题用fontsize,轴刻度用labelsize,轴标题随选用的方法而定
    def Egの大杂烩1():
        plt.title('涂鸦1',fontsize=24)  #图表标题及其字体尺寸
        plt.xlabel('x轴',fontsize=16);plt.ylabel('y轴')  #轴标题,或plt.rcParams['axes.labelsize']=16
        plt.tick_params(axis='both',labelsize=9)  #轴刻度尺寸,或plt.rcParams['xtick.labelsize']=9
        #plt.xticks([-np.pi,0,np.pi],['-π','0','π']);plt.yticks([3,7])  #轴刻度只展示这些,[]为白板
        plt.axis([dt(2017,6,1,0,0),dt(2017,9,30,0,0),9,21])  #轴刻度的展示区间:前俩x,后俩y
     
     
        x=pd.date_range('2017-6-1',periods=9,freq='2W').to_pydatetime();shuffle(x)
        y=randint(10,18,9)
        plt.plot(x,y,'og',linewidth=3)  #折线图;3参中颜色选rgb,形状如--.或圆点o,顺序随意
        plt.fill_between(x,y,randint(15,21,9),facecolor='gray',alpha=0.2)   #两对y间的填充色
        plt.scatter(x,y,60,range(9),4,plt.cm.Reds,edgecolors=(0,0.6,1)) #先浅后深的散点图,marker∈(0,11)
        plt.savefig('E:/涂鸦.png',bbox_inches='tight')
        plt.show()
    #Egの大杂烩1()
     
    def Egの大杂烩2():
        plt.title('涂鸦2',fontsize=20);plt.xlabel('x轴',fontsize=18);plt.ylabel('y轴')
        plt.xticks([-np.pi,0,np.pi,np.pi*3],['-π','0','1π','3π']);plt.yticks([-1,-0.5,0,0.5,1])
        x=np.linspace(-np.pi*2,np.pi*3,90)
        y1=np.sin(x);y2=np.cos(x)
        plt.bar(x[x>2],y1[x>2],label='直方图')
        #rgb中的单个字母是颜色,圆点o或--.等是形状,颜色和形状哪个在前随意
        plt.plot(x,y1,'bo');plt.plot(x,y2,'--.r')    #x轴,y轴,颜形;仅1个序列则为y轴,x轴自动用索引
        plt.fill_between(x,y1,y2,facecolor='gray',alpha=0.2)
        #plt.imshow(x.reshape(6,15)[:2,4:])  #参数为2维及以上的array
        plt.show()
    #Egの大杂烩2()
    ***************分割线***************
    class RandomWalk:
        def __init__(self,num=8000):
            self.x,self.y,self.num=[0],[0],num
        def steps(self):
            while len(self.x)<self.num:   #原地踏步的位移不取
                xStep,yStep=choice([-1,1])*randint(81),choice([-1,1])*randint(49)
                if not (xStep==0 and yStep==0):
                    self.x.append(self.x[-1]+xStep)
                    self.y.append(self.y[-1]+yStep)
     
    def Egの随机漫步():
        rw=RandomWalk(10000)
        rw.steps()
        plt.scatter(rw.x,rw.y,1,range(rw.num),cmap=plt.cm.Greens)
        #突出起点和终点,隐藏坐标轴
        plt.scatter(0,0,30,'red',edgecolors='none');plt.scatter(rw.x[-1],rw.y[-1],30,'blue')
        plt.axis('off')  #.imshow(*)后.show()前;藏y轴:plt.axes().get_yaxis().set_visible(False)
        plt.show()
     
    #Egの随机漫步()
  • 相关阅读:
    字符串常量池
    JDK1.8-java.lang.Object类源码阅读
    请给你的Mysql(InnoDB)表加上主键吧
    java线程占多大的内存,占哪里的内存?
    c# 多线程
    c# 遍历文件夹及其所有文件
    T-SQL 查询语句总结
    SQL Server使用LIKE运算符进行匹配查询
    sql server中关于批处理与脚本的简单介绍
    关于SQL Server数据表的五中约束
  • 原文地址:https://www.cnblogs.com/scrooge/p/7805345.html
Copyright © 2011-2022 走看看