3306 端口

  • 此前确保3306端口是打开的(服务器防火墙)
  • 在服务器中查看端口状态

    1
    netstat -an|grep 3306
  • 如果仅仅出现👇下面的信息,则说明3306端口仅仅对localhost开放,外网是无法访问的

    1
    tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN
  • 你需要找到mysql.cnf mysql 的配置文件,有可能不止一个,且不一定和我的文件名一样,

  • 找到.cnf配置文件中的,将其注释

    1
    #bind-address = 127.0.0.1
  • 如果像我这样,就说明端口是开放的,且已经有主机连接
    1.jpg

mysql用户权限

  • 在mysql的mysql表中,有用户信息
  • 查看你的用户是否允许,除localhost以外的ip访问

    1
    select host,user from user;
  • 如图,想要外网访问的用户,其对应的host应该是外网ip

  • 如果想要任意ip访问,其对应的host设置为“%
    2.jpg

  • 或者你可以直接创建一个新用户,给他权限

1
2
grant all on database_name.* to user_name@'%' identified by 'user_password';
flush privileges;

套接字类型

面向连接的套接字

- 基于TCP/IP,使用SOCKET_STREAM作为套接字类型

无连接的套接字

- 基于UDP/IP,使用SOCKET_DGRAM作为套接字类型

pyhton中的网络编程

socket模块

1
socket(socket_family, socket_type, protocol = 0)
  • 其中socket_family 是选择网络类型,本地网(AF_UNIX)还是因特网(AF_INET)
  • socket_type 是选择套接字的类型, protocaol默认为0

    套接字对象常用的方法

    • 服务器套接字
      1
      2
      3
      s.bind() #将主机号端口号绑定到套接字上
      s.listen() #设置并启动TCP监听器
      s.accept() #被动接受客户端连接
  • 客户端套接字
    1
    2
    s.connect() #主动发起TCP服务连接
    s.connect_ex() #此时会以错误码的形式抛出问题而不是一大串异常

创建一个时间戳服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from socket import *
from time import ctime
HOST = ''
PORT = 23456
ADDR = (HOST, PORT)
BUFSIZE = 1024

tcpSerSocket = socket(AF_INET,SOCK_STREAM)
tcpSerSocket.bind(ADDR)
tcpSerSocket.listen(5)

while True:
print("waiting for connection ...")
tcpCliSocket, addr = tcpSerSocket.accept()
print("connected from:", addr)
while True:
data = tcpCliSocket.recv(BUFSIZE)
if not data:
break
tcpCliSocket.send(data+b' time now:'+bytes(ctime(), 'utf-8'))
tcpCliSocket.close()
tcpSerSocket.close()

创建一个客户机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from socket import *
from time import ctime
HOST = "192.168.0.118"
PORT = 23456
ADDR = (HOST, PORT)
BUFSIZE = 1024

tcpCliSocket = socket(AF_INET, SOCK_STREAM)
tcpCliSocket.connect(ADDR)

while True:
data = input('> ')
if not data:
break

docker command help

1
docker command --help

1

use images

list images

1
docker images

2

start container by image

1
docker run -t -i ubuntu:16.04 /bin/bash

3

search images

1
docker search mysql

5

get new images

1
docker pull ubuntu:18.04

4

delete image

1
docker rmi ubuntu:18.04

6

[more operations][https://www.runoob.com/docker/docker-image-usage.html]

use container

start container

1
docker run -t -i ubuntu:16.04 /bin/bash ## -d background

show containers

1
docker ps -a

7

stop & start & restart container

1
2
3
docker start container_id ## RUN IN THE BACKGROUND
docker stop container_id
docker restart container_id

enter container

1
docker attach container_id ## use exit will stop container
1
docker exec -it container_id /bin/bash  ## use exit will not stop container

export container

1
docker export container_id > container.tar

import container_snap to image

1
cat docker/mysql.tar | docker import - mysql:v1

8

delete container

1
docker rm -f container_id

show container’s port mapping

1
docker port container_id

9

connect container by port mapping

1
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD = 123456 mysql

connect containers

create a docker network

1
docker network create -d bridge hadoop-net

show networks

1
docker network ls

run a container and connect to the network

1
docker run -itd --name hadoop1 --network hadoop-net ubuntu /bin/bash

数据分析—-数据清洗

一、导入数据

1
2
3
4
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
import xlrd
1
2
df = DataFrame(pd.read_excel('datas/grades.xlsx')) 
print(df)
   Unnamed: 0  Unnamed: 1  Unnamed: 2  Unnamed: 3
0         蒋广佳        43.0        69.0        61.0
1          廖菲        80.0        64.0        62.0
2         沈秀玲        68.0        74.0        98.0
3          韦丹        48.0        53.0        64.0
4         张梦雅        72.0        73.0        96.0
5         赵雅欣        60.0         NaN        70.0
6         曹海广        74.0        60.0        20.0
7         陈泽灿        38.0        21.0        92.0
8         NaN        88.0        67.0        84.0
9         高海亮        86.0        74.0        96.0
10        顾晓冬        84.0        60.0        90.0
11        侯星宇        64.0       111.0         NaN
12        江宜哲        60.0        33.0        70.0
13        NaN         NaN         NaN         NaN
14        梁杨杨        68.0        54.0        94.0
15         刘辉         NaN        63.0        98.0
16        罗嘉豪        39.0        44.0        56.0
17        施亚君        90.0        63.0        90.0
18         孙添        64.0        63.0        78.0
19         王杰        74.0         NaN        76.0
20         王泽        52.0        48.0        94.0
21        NaN        60.0        69.0        74.0
22        杨福程        70.0        49.0        76.0
23        尤澳晨        91.0        67.0        86.0
24         翟佳        78.0        73.0        88.0
25         张旭       100.0        60.0        98.0
26        支星哲        80.0        63.0       100.0
27        邹湘涛        54.0        40.0        90.0
  • 我们可以看见上面的数据是缺少标注的,列名缺少标注;并且有很多是空值,因此我们要对数据进行清洗,提高数据的质量。在这里数据清洗有四个要点简称“完全合一”
    • 整性:单条数据是否完整,统计的字段是否完善。
    • 面性:观察某一列的全部数值,选中一列,我们可以看到最大值,最小值,平均值。我们可以通过常识判断数据是否合理,比如:数据定义、单位标识、数值本身。
    • 法性:数据的类型、内容、大小的合法性。比如数据中存在非ASCII字符,性别存在未知,总分超过100等。
    • 性:数据是否存在重复记录,由于数据来源于不同的渠道,重复的情况是非常常见的。行数据、列数据都需要是唯一的。
  • 事实上数据清洗的标准有差不多七八条,有兴趣的可以了解一下,这里归纳为“完全合一”四条,按照这四条基本上可以解决数据清洗中的大部分问题,使得数据标准、干净、连续

二、开始数据清洗

1、完整性

problem 1:空行

  • solution: 删除
1
df.dropna(how="all",inplace=True)

problem 2:缺失值

  • solution:
    • 删除:删除数据缺失的记录
    • 均值:使用当前列的均值
    • 高频:使用当前列出现平率最高的数据
  • 首先我们先把列的标注补上
1
df = df.rename(columns={'Unnamed: 0':'index','Unnamed: 1':'math','Unnamed: 2':'english','Unnamed: 3':'c++'})
1
df = df.drop(columns='index')
1
print(df)
     math  english    c++
0    43.0     69.0   61.0
1    80.0     64.0   62.0
2    68.0     74.0   98.0
3    48.0     53.0   64.0
4    72.0     73.0   96.0
5    60.0      NaN   70.0
6    74.0     60.0   20.0
7    38.0     21.0   92.0
8    88.0     67.0   84.0
9    86.0     74.0   96.0
10   84.0     60.0   90.0
11   64.0    111.0    NaN
12   60.0     33.0   70.0
14   68.0     54.0   94.0
15    NaN     63.0   98.0
16   39.0     44.0   56.0
17   90.0     63.0   90.0
18   64.0     63.0   78.0
19   74.0      NaN   76.0
20   52.0     48.0   94.0
21   60.0     69.0   74.0
22   70.0     49.0   76.0
23   91.0     67.0   86.0
24   78.0     73.0   88.0
25  100.0     60.0   98.0
26   80.0     63.0  100.0
27   54.0     40.0   90.0
  • 现在我们想对df[‘math’]中缺失的值用平均值代替
1
df['math'].fillna(df['math'].mean(),inplace=True)
1
print(df)
          math  english    c++
0    43.000000     69.0   61.0
1    80.000000     64.0   62.0
2    68.000000     74.0   98.0
3    48.000000     53.0   64.0
4    72.000000     73.0   96.0
5    60.000000      NaN   70.0
6    74.000000     60.0   20.0
7    38.000000     21.0   92.0
8    88.000000     67.0   84.0
9    86.000000     74.0   96.0
10   84.000000     60.0   90.0
11   64.000000    111.0    NaN
12   60.000000     33.0   70.0
13   68.653846      NaN    NaN
14   68.000000     54.0   94.0
15   68.653846     63.0   98.0
16   39.000000     44.0   56.0
17   90.000000     63.0   90.0
18   64.000000     63.0   78.0
19   74.000000      NaN   76.0
20   52.000000     48.0   94.0
21   60.000000     69.0   74.0
22   70.000000     49.0   76.0
23   91.000000     67.0   86.0
24   78.000000     73.0   88.0
25  100.000000     60.0   98.0
26   80.000000     63.0  100.0
27   54.000000     40.0   90.0
  • 如果想用最高频率的数据对english进行填充,可以通过value_counts获取math字段最高频次english_maxf,然后对其进行填充
1
english_maxf = df['english'].value_counts().index[0]
1
df['english'].fillna(english_maxf,inplace=True)
1
print(df)
          math  english    c++
0    43.000000     69.0   61.0
1    80.000000     64.0   62.0
2    68.000000     74.0   98.0
3    48.000000     53.0   64.0
4    72.000000     73.0   96.0
5    60.000000     63.0   70.0
6    74.000000     60.0   20.0
7    38.000000     21.0   92.0
8    88.000000     67.0   84.0
9    86.000000     74.0   96.0
10   84.000000     60.0   90.0
11   64.000000    111.0    NaN
12   60.000000     33.0   70.0
13   68.653846     63.0    NaN
14   68.000000     54.0   94.0
15   68.653846     63.0   98.0
16   39.000000     44.0   56.0
17   90.000000     63.0   90.0
18   64.000000     63.0   78.0
19   74.000000     63.0   76.0
20   52.000000     48.0   94.0
21   60.000000     69.0   74.0
22   70.000000     49.0   76.0
23   91.000000     67.0   86.0
24   78.000000     73.0   88.0
25  100.000000     60.0   98.0
26   80.000000     63.0  100.0
27   54.000000     40.0   90.0

2、全面性

problem:列数据单位不统一

solution:将不同的单位的找出来,将其进行迭代替换,比如说将榜(lbs)转化为千克(kgs)

1
2
3
4
5
6
7
8
# 获取 weight 数据列中单位为 lbs 的数据
rows_with_lbs = df['weight'].str.contains('lbs').fillna(False)
print df[rows_with_lbs]
# 将 lbs 转换为 kgs, 2.2lbs=1kgs
for i,lbs_row in df[rows_with_lbs].iterrows():
# 截取从头开始到倒数第三个字符之前,即去掉 lbs。
weight = int(float(lbs_row['weight'][:-3])/2.2)
df.at[i,'weight'] = '{}kgs'.format(weight)

3、合理性

problem:非ASCII字符

solution:对于非ASCII字符,我们可以采用删除或者替换的方式,我们直接选择删除

1
df['name'].replace({r'[^\x00-\x7f]+':''},regex=True,inplace=True)

4、唯一性

problem1:一列有多个参数

solution:比如英文名字,是有两部分组成的,包含两个参数Firstname、Lastnamr,我们需要将name一列拆分为Firstname和Lastname两个字段,我们可以采用split方法,对其进行切分

1
2
df['First_namr','Last_name'] = df['name'].str.split(expand=True)
df.drop('name',axis=1,inplace=True)

problem2:重读数据

solution:我们校验数据是否存在重复数据,如果有重复数据,如果就用pandas提供的drop_duplicates()来删除重复数据。

1
df.drop_duplicates(['First_name','Last_name'],inplace=True)

分析热评的请求URL

  • 首先我们先对请求抓包,发现所有的评论都包含在 https://music.163.com/weapi/v1/resource/comments/R_SO_4_32785700?csrf_token="里面,然后再去分析这个请求,发现这是一个POST请求,请求参数由两个params以及encSecKey。好了到此我们需要的东西都有了,接下来我们分析如何去得到这两个参数。

    找到请求

    1.png

    分析请求参数

    2.png

    分析js加密

  • 找到全局js文件,找到两个参数所在的位置
    3.png
  • 发现这两个参数是由window.asrsea获得的,接着去定位到这个函数找到对应的原函数d
    4.ong
  • 对js进行调试,发现d的四个参数,有三个是定值,这个函数还用到了a、b、c三个函数
    5
  • 其中a是产生一个16位的随机数(这里我直接让它等于FwtEYduOXlNEHbLP)为什么要等与这个呢 hhh 因为我发现这个随机数,他在生成encText的时候用了一次,生成encSecKey的时候,又用了一次,而且encSecKey就只跟这个随机数相关,所以让这个随机数为定值的话,就可以直接得到encSecKey的值,不用再去搞一个rsa加密,为了让你们看清楚,我还是把贴出来把
    6
  • b函数就是我们主要要解决的AES加密,经过调试,我们可以知道它的两个参数a、b分别是加密字符转、密钥。以及AES的偏移量为0102030405060708、加密模式为CBC
    7
  • 接下来看c函数,c函数其实是RSA加密,获取encSecKey的值的他的三个参数,只有a是变量,是我们随机生成的16为随机数,这里我们就默认为定值,b、c应该是和rsa加密有关的参数,应为本身并没有学过加密,这里我就不多说了,但是经过调试,我们可以知道b、c是定值 b =010001 c是一大串字符串。见下图。
    8
  • 最后我们具体分析一下d函数,经过N次调试,我发现这其实和我的想法差不多,h是一个字典,包含了我们需要的两个参数。encText是由两次AES加密产生的及两次b,加密字符串是一样的,然后密钥第一次是个定值0CoJUm6Qyw8W8jud,第二次是16位随机数,也相当于定值。所以encText就出来了,params是由一次RSA加密产生的,并且只与16位的随机数有关,这里就清楚为什么我让随机数直接等于FwtEYduOXlNEHbLP,哈哈。因为我调试的时候,刚好出现了这么个随机数,于是我就直接拿过来用了,这个随机数对应的encSecKey = 81e7a41af9830200d5606be1a632e57eb0006b3cdae579127115c6323d4c4802f3af9efcee21d9f4126dde266773cbd795f19ae44028f9f8d038cd62d2816952fa99bb61ecb5fba87d5b178ff4b982ee34c7491808f7cb774554a0235a210caf2e5e867a0e2ebdf6f994be1b198ab43b14ce1f7cfa6f80b9070dea5fc5d6c712

    用python重写js加密

  • 经过js加密码的分析,我用python实现了一下AES加密,具体代码如下,包含两个参数,一个是需要加密的字符串,一个是密钥具体如下

    1
    2
    3
    4
    5
    6
    7
    def AES_encrypt(text, key):
    pad = 16 - len(text) % 16
    text = text + pad * chr(pad)
    encryptor = AES.new(key, AES.MODE_CBC, "0102030405060708")
    encrypt_text = encryptor.encrypt(text)
    encrypt_text = base64.b64encode(encrypt_text)
    return encrypt_text
  • 两次调用这个函数。得到结果与调试的结果对比,一模一样。哈哈,上代码、上图

    1
    2
    3
    4
    f_key = "0CoJUm6Qyw8W8jud"
    text = "{\"rid\":\"R_SO_4_32785700\",\"offset\":\"20\",\"total\":\"true\",\"limit\":\"20\",\"csrf_token\":\"\"}"
    rs = AES_encrypt(text, f_key)
    params = AES_encrypt(str(rs)[2:-1], "FwtEYduOXlNEHbLP")

    这里解释一下,text是我进过N次调试得出的,因为在请求评论之前,text有好几个值来验证其他的东西,这里我大概理解了一下text的含义,这里我们只要知道offset是偏移量,limit是每次请求多少条,比如你请求前二十条则offset=0,limit = 20,我上面的是请求20-40条。

  • 然后直接获取的encSecKey直接赋值就好啦,结合这两个参数,我们的请求参数就构造好了,直接POST吧,就能得到评论啦,哈哈,上代码,上图

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     data = {
    'params': params,
    'encSecKey': encSecKey
    }
    headers = {
    'Accept-Language':"zh-CN,zh;q=0.9,en;q=0.8",
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',

    'Cookie': 'appver=1.5.0.75771',
    'Referer': 'http://music.163.com/'
    }
    url = "https://music.163.com/weapi/v1/resource/comments/R_SO_4_32785700?csrf_token="
    raw = requests.post(url,headers=headers, data=data)
    print(raw.json())

解析json,获取评论

git简单指令

首先放一张学习路线

git学习路线

1、创建版本库

1
2
3
mkdir huzai //创建一个空目录
cd huzai //进入此目录
git init //初始化git仓库

2、添加文件到版本库

1
2
git add file  //将文件添加到缓存区
git commit -m "post message" //提交并附带提交信息

3、版本回退

1
2
3
git reset --hard HEAD^ //HEAD是一个指针,指向当前的版本,^代表上一代版本,HEAD^^代表上两代
git reflog //查询每次提交的commit_id
git reset --hard commit_id //根据id进行回退

4、管理修改

1
git diff HEAD -- file //查看工作区(file)与最新版本(HEAD)的区别

5、撤销修改

1
2
3
4
git checkout -- file //直接丢弃工作区的修改(可用于恢复误删的文件)
//对于已经添加到缓存的修改
git reset HEAD file //撤销缓存区的修改
git checkout -- file

6、删除文件

1
2
3
rm file //删除本地文件
git rm file //删除版本库中的文件
git commit -m "post delete" //提交删除事务

7、连接远程仓库

1
2
3
4
5
6
7
//先生成连接密钥
ssh-kengen -t rsa -C username
//将id_rsa.pub中的内容复制到github的密钥管理中
//再根据github的提示将本地仓库与远程仓库进行关联
git remote add origin git@github.com:username/repository
//再推送master分支的所有内容到远程仓库
git push -u origin master

8、从远程仓库进行下载

1
git clone git@github.com:username/repository

9、创建新的分支并切换到该分支下

1
2
3
git checkout -b branchname //创建并切换
git branch branch_name //创建
git checkout branch_name //切换

10、合并指定分支到当前分支

1
git merge branch_name

11、删除分支

1
git branch -d branch_name

12、如果合并时出现冲突

1
2
cat conflic_filename
//git 会用<<<<< ===== >>>>>>显示不同分支的内容,你则需要手动解决冲突

13、分支管理策略

master分支应该是非常稳定的,也就是用于发布最新版本的,平时不应该在上面干活,干活都应该在dev分支上
也就是说dev分支是不稳定的,到了某个时候将dev分支合并到master分支上,你和你的小伙伴应该在各自的分支上干活,然后推送到dev分支上

14、bug分支

1
2
3
4
git add now_file
git stash //保护现场
//这里修改bug
git stash pop //提取现场,继续工作

15、丢弃一个没有被合并的分支

1
git branch -D branch_name

16、多人协作

1、尝试git push origin branch_name
2、如果推送失败,说明远程分支比你的版本新,则你git pull 拉取远程文件
3、合并你两的分支,如果有冲突则手动解决问题
4、重复1

  • 注:如果git pull 提示 no tracking information 则说明远程分支和本地分支没有关联用下面的命令进行关联
    1
    git branch --set-uostream-to branch_name origin/branch_name

或者你不知道有什么分支

1
2
3
git remote -v //查看远程仓库的信息
git checkout -b branch_name origin/branch_name //创建本地分支以及远程分支
git branch --set-upstream-to branch_name origin/branch_name //进行关联

git

数据分析—-pandas

核心数据结构 Series & DataFrame

1
2
3
import pandas as pd
import numpy as np
from pandas import Series, DataFrame

Series是一个定长的字典序列,它有两个基本属性index 、 value index 默认是 0 ,1,2,3 递增的,也可以自己指定索引 index=[‘a’, ‘b’, ‘c’]

创建Series的三种方式

1
2
3
4
5
6
7
x1 = Series([1,2,3,4])
x2 = Series(data=[1,2,3,4],index=['a','b','c','d'])
dic = {'a':1,'b':2,'c':3,'d':4}
x3 = Series(dic)
print(x1)
print(x2)
print(x3)
0    1
1    2
2    3
3    4
dtype: int64
a    1
b    2
c    3
d    4
dtype: int64
a    1
b    2
c    3
d    4
dtype: int64

DataFrame类似数据库中的表,可以将其看成是由有相同的索引的Series组成

创建DataFra几种方式

1
2
3
data = {"chinese":[90,80,70,60,50],'math':[70,80,70,90,60],'english':[30,50,70,80,60]}
df1 = DataFrame(data=data,index=['zhangfei','guanyu','zhaoyun','huangzhong','machao'])
print(df)
            chinese  english  math
zhangfei         90       30    70
guanyu           80       50    80
zhaoyun          70       70    70
huangzhong       60       80    90
machao           50       60    60
1
2
3
import xlrd
df2 = DataFrame(pd.read_excel('datas/grades.xlsx'))
df2 = df2.drop_duplicates()
1
print(df2)
     姓名   高数  英语  C++
0   蒋广佳   43  69   61
1    廖菲   80  64   62
2   沈秀玲   68  74   98
3    韦丹   48  53   64
4   张梦雅   72  73   96
5   赵雅欣   60  63   70
6   曹海广   74  60   20
7   陈泽灿   38  21   92
8    邓杰   88  67   84
9   高海亮   86  74   96
10  顾晓冬   84  60   90
11  侯星宇   64  69   96
12  江宜哲   60  33   70
13  李洪汀   76  56   84
14  梁杨杨   68  54   94
15   刘辉   68  63   98
16  罗嘉豪   39  44   56
17  施亚君   90  63   90
18   孙添   64  63   78
19   王杰   74  60   76
20   王泽   52  48   94
21  徐孟圆   60  69   74
22  杨福程   70  49   76
23  尤澳晨   91  67   86
24   翟佳   78  73   88
25   张旭  100  60   98
26  支星哲   80  63  100
27  邹湘涛   54  40   90

数据清洗

删除不必要的行或列

1
2
3
#删除行
df2 = df2.drop(columns=['姓名'])
print(df2)
     高数  英语  C++
0    43  69   61
1    80  64   62
2    68  74   98
3    48  53   64
4    72  73   96
5    60  63   70
6    74  60   20
7    38  21   92
8    88  67   84
9    86  74   96
10   84  60   90
11   64  69   96
12   60  33   70
13   76  56   84
14   68  54   94
15   68  63   98
16   39  44   56
17   90  63   90
18   64  63   78
19   74  60   76
20   52  48   94
21   60  69   74
22   70  49   76
23   91  67   86
24   78  73   88
25  100  60   98
26   80  63  100
27   54  40   90
1
2
3
#删除列
df2 = df2.drop(index = [27])
print(df2)
     高数  英语  C++
0    43  69   61
1    80  64   62
2    68  74   98
3    48  53   64
4    72  73   96
5    60  63   70
6    74  60   20
7    38  21   92
8    88  67   84
9    86  74   96
10   84  60   90
11   64  69   96
12   60  33   70
13   76  56   84
14   68  54   94
15   68  63   98
16   39  44   56
17   90  63   90
18   64  63   78
19   74  60   76
20   52  48   94
21   60  69   74
22   70  49   76
23   91  67   86
24   78  73   88
25  100  60   98
26   80  63  100

重命名列名

1
df2 = df2.rename(columns={'高数':'math','英语':'english'})

去除重复的值

1
df2 = df2.drop_duplicates()

更改数据格式

1
2
df2['math'] = df2['math'].astype('str')
#df2['math'].astype(np.int64)

清除数据间的空格

1
2
df2['math'] = df2['math'].map(str.strip) #删除左右两边的空格
df2['math'] = df2['math'].map(str.lstrip) #删除左边的空格(str.rstrip 右边的空格)

删除指定字符

1
df2['math'] = df2['math'].str.strip('$')

大小写转换

1
df2.columns = df2.columns.str.upper() #全部大写(lower()全部小写 title()首字母大写)
1
df2















































































































































































MATH ENGLISH C++
0 43 69 61
1 80 64 62
2 68 74 98
3 48 53 64
4 72 73 96
5 60 63 70
6 74 60 20
7 38 21 92
8 88 67 84
9 86 74 96
10 84 60 90
11 64 69 96
12 60 33 70
13 76 56 84
14 68 54 94
15 68 63 98
16 39 44 56
17 90 63 90
18 64 63 78
19 74 60 76
20 52 48 94
21 60 69 74
22 70 49 76
23 91 67 86
24 78 73 88
25 100 60 98
26 80 63 100

使用apply函数对数据进行清洗

1
2
3
#df2['MATH'] = df2['MATH'].apply(str.lower)
df2['MATH'] = df2['MATH'].astype(np.int64)
df2















































































































































































MATH ENGLISH C++
0 43 69 61
1 80 64 62
2 68 74 98
3 48 53 64
4 72 73 96
5 60 63 70
6 74 60 20
7 38 21 92
8 88 67 84
9 86 74 96
10 84 60 90
11 64 69 96
12 60 33 70
13 76 56 84
14 68 54 94
15 68 63 98
16 39 44 56
17 90 63 90
18 64 63 78
19 74 60 76
20 52 48 94
21 60 69 74
22 70 49 76
23 91 67 86
24 78 73 88
25 100 60 98
26 80 63 100

1
2
3
4
def plus(df):
df['Total'] = df['MATH']+df['ENGLISH']+df['C++']
return df
df2 = df2.apply(plus,axis=1)
1
print(df2)
    MATH  ENGLISH  C++  Total
0     43       69   61    173
1     80       64   62    206
2     68       74   98    240
3     48       53   64    165
4     72       73   96    241
5     60       63   70    193
6     74       60   20    154
7     38       21   92    151
8     88       67   84    239
9     86       74   96    256
10    84       60   90    234
11    64       69   96    229
12    60       33   70    163
13    76       56   84    216
14    68       54   94    216
15    68       63   98    229
16    39       44   56    139
17    90       63   90    243
18    64       63   78    205
19    74       60   76    210
20    52       48   94    194
21    60       69   74    203
22    70       49   76    195
23    91       67   86    244
24    78       73   88    239
25   100       60   98    258
26    80       63  100    243

pandas中常用的统计函数

1.jpg

1
print(df2.describe())
             MATH    ENGLISH         C++       Total
count   27.000000  27.000000   27.000000   27.000000
mean    69.444444  59.703704   81.148148  210.296296
std     16.113380  12.406000   17.933003   34.410212
min     38.000000  21.000000   20.000000  139.000000
25%     60.000000  55.000000   72.000000  193.500000
50%     70.000000  63.000000   86.000000  216.000000
75%     80.000000  68.000000   95.000000  239.500000
max    100.000000  74.000000  100.000000  258.000000
1
2