数据分析基本技能
1 文件读取与写入
txt文件写入
file = open('test.txt','w',encoding='utf-8')
file.write('Python') # 写入内容为字符串格式
file.close() # 调用关闭文件的函数,避免异常错误
txt文件读取
file = open('test.txt','r') # 读取时可不使用“encoding=”,不同系统的编码格式不一样
data = file.readlines() # .readlines()将所有数据放入一个列表中
print(data)
file.close()
csv文件写入
import csv
with open('test.csv','w',encoding='utf-8',newline='') as fp:
writer = csv.writer(fp)
writer.writerow(需要写入的内容)
csv文件读取
with open('test.csv','r',encoding='utf-8') as fp:
reader = csv.reader(fp)
next(reader) # 跳过标题行
print([row for row in reader])
xls文件写入
import xlwt
f = xlwt.Workbook(encoding='utf-8')
sheet = f.add_sheet('test') # 创建表并命名
sheet.write(0,0,'A') # write()函数三个值分别为行、列、写入内容(在xls文件中,坐标以及索引都是从0开始的)
f.save('test.xls') # 保存创建的xls文件
xls文件读取
import xlrd
file = xlrd.open_workbook('test.xls') # 打开文件
sheet1 = file.sheets()[0] # 读取文件sheet,第一张表sheet1对应值为[0]
row = sheet1.row_values(0) # 读取表1的第一行
col = sheet1.col_values(0) # 读取表1的第一列
print(row)
print(col)
2 Pandas
数据结构
主要数据结构:Series(一维数据)、DataFrame(二维数据)
DataFrame
DataFrame是一个表格型的数据结构,含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。既有行索引也有列索引,可以看做是由Series组成的字典(共同用一个索引)
函数:
pandas.DataFrame(data,index,columns,dtype,copy)
参数说明:
参数 | 说明 |
---|---|
data | 一组数据(ndarray、series、map、list、dict等) |
index | 索引值,或者称为行标签 |
columns | 列标签,默认为RangeIndex(0,1,2,…,n) |
dtype | 默认自动判断 |
copy | 拷贝数据,默认为False |
import pandas as pd
data = {'name':['John','Mike','Shorn'],'age':[18,19,21]}
data_change = pd.DataFrame(data)
print(data_change)
name | age | |
---|---|---|
0 | John | 18 |
1 | Mike | 19 |
2 | Shorn | 21 |
Pandas可以使用loc属性返回指定行的数据,如果未设置索引,默认从0开始
import pandas as pd
data = {'name':['John','Mike','Shorn'],'age':[18,19,21]}
data_change = pd.DataFrame(data)
print(data_change.loc[0])
name John
age 18
Name: 0, dtype: object
Series
Series类似表格中的一列(column),类似于一维数组,可以保存任何数据类型。Series由索引和列组成。
函数:
pandas.Series(data,index,dtype,name,copy)
参数说明:
参数 | 说明 |
---|---|
data | 一组数据(ndarray) |
index | 数据索引标签,默认从0开始 |
dtype | 默认自动判断 |
name | 设置名称,默认无 |
copy | 拷贝数据,默认为False |
import pandas as pd
data = [1,2,3]
result = pd.Series(data,name='test')
print(result)
0 1
1 2
2 3
Name: test, dtype: int64
CSV文件
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data)
Name Region Address UnitName Room No Count Room Count Hall \
0 怡心苑 浦东 花山路609弄 1 602 4.0 3
1 怡心苑 浦东 花山路609弄 1 502 3.0 1
2 怡心苑 浦东 花山路609弄 1 601 2.0 1
3 怡心苑 浦东 花山路609弄 1 402 3.0 1
4 怡心苑 浦东 花山路609弄 1 501 1.0 1
... ... ... ... ... ... ... ...
1035 怡心苑 浦东 花山路609弄 70 701 4.0 1
1036 怡心苑 浦东 花山路609弄 70 602 3.0 2
1037 怡心苑 浦东 花山路609弄 70 501 4.0 1
1038 怡心苑 浦东 花山路609弄 70 401 4.0 1
1039 怡心苑 浦东 花山路609弄 70 402 3.0 2
Encrypt House Area Total Floor
0 \U000f6407\U000f6522\U000f6491.\U000f64c1\U000... 6
1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
2 \U000f63a5\U000f6540.\U000f6386\U000f64c1 6
3 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
4 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
... ... ...
1035 \U000f87cb\U000f87cb\U000f86f1.\U000f8759\U000... 11
1036 \U000f87cb\U000f8726\U000f8830.\U000f878d\U000... 11
1037 \U000f87cb\U000f87cb\U000f86f1.\U000f8759\U000... 11
1038 \U000f87cb\U000f87cb\U000f86f1.\U000f8759\U000... 11
1039 \U000f87cb\U000f8726\U000f8830.\U000f878d\U000... 11
[1040 rows x 9 columns]
正常情况下,输出结果为数据的前5行和末尾5行,中间部分以**…**代替,如果列数过多,就会像这里一样换行输出。
如果想显示全部数据,可以使用**to_string()**函数
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.to_string())
Name Region Address UnitName Room No Count Room Count Hall Encrypt House Area Total Floor
0 怡心苑 浦东 花山路609弄 1 602 4.0 3 \U000f6407\U000f6522\U000f6491.\U000f64c1\U000f63a5 6
1 怡心苑 浦东 花山路609弄 1 502 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
2 怡心苑 浦东 花山路609弄 1 601 2.0 1 \U000f63a5\U000f6540.\U000f6386\U000f64c1 6
3 怡心苑 浦东 花山路609弄 1 402 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
4 怡心苑 浦东 花山路609弄 1 501 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
5 怡心苑 浦东 花山路609弄 1 302 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
6 怡心苑 浦东 花山路609弄 1 401 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
7 怡心苑 浦东 花山路609弄 1 202 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
8 怡心苑 浦东 花山路609弄 1 301 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
9 怡心苑 浦东 花山路609弄 1 102 2.0 2 \U000f63a5\U000f6522.\U000f6458\U000f6511 6
10 怡心苑 浦东 花山路609弄 1 201 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
11 怡心苑 浦东 花山路609弄 1 101 1.0 1 \U000f64c1\U000f6407.\U000f6491\U000f6458 6
12 怡心苑 浦东 花山路609弄 2 102 2.0 1 \U000f6540\U000f6380.\U000f6407\U000f6407 6
13 怡心苑 浦东 花山路609弄 2 201 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
14 怡心苑 浦东 花山路609弄 2 101 2.0 1 \U000f6540\U000f6380.\U000f6407\U000f6407 6
15 怡心苑 浦东 花山路609弄 2 602 4.0 3 \U000f6407\U000f64c1\U000f6491.\U000f6491\U000f6522 6
16 怡心苑 浦东 花山路609弄 2 502 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
17 怡心苑 浦东 花山路609弄 2 601 4.0 3 \U000f6407\U000f64c1\U000f6491.\U000f6491\U000f6522 6
18 怡心苑 浦东 花山路609弄 2 402 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
19 怡心苑 浦东 花山路609弄 2 501 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
20 怡心苑 浦东 花山路609弄 2 302 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
21 怡心苑 浦东 花山路609弄 2 401 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
22 怡心苑 浦东 花山路609弄 2 202 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
23 怡心苑 浦东 花山路609弄 2 301 2.0 2 \U000f6540\U000f6458.\U000f6522\U000f6511 6
24 怡心苑 浦东 花山路609弄 3 302 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
25 怡心苑 浦东 花山路609弄 3 401 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
26 怡心苑 浦东 花山路609弄 3 202 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
27 怡心苑 浦东 花山路609弄 3 301 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
28 怡心苑 浦东 花山路609弄 3 102 1.0 1 \U000f64c1\U000f6407.\U000f6491\U000f6458 6
29 怡心苑 浦东 花山路609弄 3 201 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
30 怡心苑 浦东 花山路609弄 3 101 2.0 2 \U000f63a5\U000f6522.\U000f6458\U000f6511 6
31 怡心苑 浦东 花山路609弄 3 602 2.0 1 \U000f63a5\U000f6540.\U000f6386\U000f64c1 6
32 怡心苑 浦东 花山路609弄 3 502 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
33 怡心苑 浦东 花山路609弄 3 601 4.0 3 \U000f6407\U000f6522\U000f6491.\U000f64c1\U000f63a5 6
34 怡心苑 浦东 花山路609弄 3 402 1.0 1 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
35 怡心苑 浦东 花山路609弄 3 501 3.0 1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
36 怡心苑 浦东 花山路609弄 4 502 3.0 2 \U000f6407\U000f6386\U000f6458.\U000f6540\U000f6458 6
37 怡心苑 浦东 花山路609弄 4 601 4.0 3 \U000f6407\U000f6540\U000f6511.\U000f63a5\U000f6491 6
38 怡心苑 浦东 花山路609弄 4 402 3.0 2 \U000f6407\U000f6386\U000f6458.\U000f6540\U000f6458
(由于数据过多,这里截取部分数据)
可以使用**to_csv()**函数将DataFrame存储为csv文件:
import pandas as pd
data = {'name':['John','Mike','Shorn'],'age':[18,19,21]}
data_change = pd.DataFrame(data)
data_change.to_csv('test.csv')
JSON文件
import pandas as pd
data = pd.read_json('test.json')
print(data.to_string())
id name url likes
0 A001 菜鸟教程 www.runoob.com 61
1 A002 Google www.google.com 124
2 A003 淘宝 www.taobao.com 45
从URL中读取JSON数据:
import pandas as pd
URL = 'https://static.runoob.com/download/sites.json'
df = pd.read_json(URL)
print(df)
id name url likes
0 A001 菜鸟教程 www.runoob.com 61
1 A002 Google www.google.com 124
2 A003 淘宝 www.taobao.com 45
数据处理
head()函数
head(n)用于读取前面的n行,如果不填参数n,默认返回前5行。
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.head())
Name Region Address UnitName Room No Count Room Count Hall \
0 怡心苑 浦东 花山路609弄 1 602 4.0 3
1 怡心苑 浦东 花山路609弄 1 502 3.0 1
2 怡心苑 浦东 花山路609弄 1 601 2.0 1
3 怡心苑 浦东 花山路609弄 1 402 3.0 1
4 怡心苑 浦东 花山路609弄 1 501 1.0 1
Encrypt House Area Total Floor
0 \U000f6407\U000f6522\U000f6491.\U000f64c1\U000... 6
1 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
2 \U000f63a5\U000f6540.\U000f6386\U000f64c1 6
3 \U000f6540\U000f6386.\U000f6522\U000f63a5 6
4 \U000f64c1\U000f6491.\U000f63a5\U000f6511 6
tail()函数
tail(n)用于读取尾部的n行,如果不填参数n,默认返回末尾5行,空行各个字段的值返回NaN。
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.tail())
Name Region Address UnitName Room No Count Room Count Hall \
1035 怡心苑 浦东 花山路609弄 70 701 4.0 1
1036 怡心苑 浦东 花山路609弄 70 602 3.0 2
1037 怡心苑 浦东 花山路609弄 70 501 4.0 1
1038 怡心苑 浦东 花山路609弄 70 401 4.0 1
1039 怡心苑 浦东 花山路609弄 70 402 3.0 2
Encrypt House Area Total Floor
1035 \U000f87cb\U000f87cb\U000f86f1.\U000f8759\U000... 11
1036 \U000f87cb\U000f8726\U000f8830.\U000f878d\U000... 11
1037 \U000f87cb\U000f87cb\U000f86f1.\U000f8759\U000... 11
1038 \U000f87cb\U000f87cb\U000f86f1.\U000f8759\U000... 11
1039 \U000f87cb\U000f8726\U000f8830.\U000f878d\U000... 11
info()函数
返回表格的一些基本信息
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1040 entries, 0 to 1039
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Name 1040 non-null object
1 Region 1040 non-null object
2 Address 1040 non-null object
3 UnitName 1040 non-null int64
4 Room No 1040 non-null object
5 Count Room 957 non-null float64
6 Count Hall 1040 non-null int64
7 Encrypt House Area 1040 non-null object
8 Total Floor 1040 non-null int64
dtypes: float64(1), int64(3), object(5)
memory usage: 73.3+ KB
None
describe()函数
显示数据的基本统计信息,包括均值、方差、最值等
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.describe())
UnitName Count Room Count Hall Total Floor
count 1040.000000 957.000000 1040.000000 1040.000000
mean 37.250000 2.754441 1.717308 8.980769
std 19.938766 0.799643 0.642487 2.489558
min 1.000000 1.000000 0.000000 5.000000
25% 23.000000 2.000000 2.000000 6.000000
50% 35.000000 3.000000 2.000000 11.000000
75% 57.000000 3.000000 2.000000 11.000000
max 70.000000 4.000000 3.000000 11.000000
shape函数
显示数据的行数和列数
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.shape)
(1040, 9)
清洗空值:
dropna()函数
DataFrame.dropna(axis=0,how='any',thresh=None,subset=None,inplace=False)
参数说明:
参数 | 说明 |
---|---|
axis | 默认为0,表示遇到空值删除整行,如果设置参数axis=1表示遇到空值删除整列 |
how | 默认为 ‘any’ 如果一行(或一列)里任何一个数据有出现 NA 就去掉整行,如果设置 how=‘all’ 一行(或列)都是 NA 才去掉这整行 |
thresh | 设置需要多少非空值的数据才可以保留下来的 |
subset | 设置想要检查的列。如果是多个列,可以使用列名的 list 作为参数 |
inplace | 如果设置 True,将计算得到的值直接覆盖之前的值并返回 None,修改的是源数据 |
在做数据清洗的时候可以通过**isnull()**判断各个单元格是否为空
import pandas as pd
data = pd.read_csv('怡心苑.csv')
print(data.isnull())
Name Region Address UnitName Room No Count Room Count Hall \
0 False False False False False False False
1 False False False False False False False
2 False False False False False False False
3 False False False False False False False
4 False False False False False False False
... ... ... ... ... ... ... ...
1035 False False False False False False False
1036 False False False False False False False
1037 False False False False False False False
1038 False False False False False False False
1039 False False False False False False False
Encrypt House Area Total Floor
0 False False
1 False False
2 False False
3 False False
4 False False
... ... ...
1035 False False
1036 False False
1037 False False
1038 False False
1039 False False
[1040 rows x 9 columns]
空值:True 非空值:False
还可以指定空数据类型
import pandas as pd
missing_values = ['n/a','--']
data = pd.read_csv('怡心苑.csv',na_values = missing_values)
print(data.isnull())
删除包含空数据的行
import pandas as pd
data = pd.read_csv('tets_data.csv')
new_data = data.dropna()
print(new_data.to_string())
注意!!!默认情况下,dropna()函数返回一个新的DataFrame,不会修改源数据。如果想要修改源数据DataFrame,可以使用inplace=True参数。
import pandas as pd
data = pd.read_csv('tets_data.csv')
new_data = data.dropna(inplace=True)
print(new_data.to_string())
删除指定列有空值的行
import pandas as pd
data = pd.read_csv('tets_data.csv')
new_data = data.dropna(sunset=['Region'],inplace=True)
print(new_data.to_string())
fillna()函数
**fillna()**函数替换空值
import pandas as pd
data = pd.read_csv('tets_data.csv')
new_data = data.fillna(X,inplace=True)
print(new_data.to_string())
替换某一列的空值
import pandas as pd
data = pd.read_csv('tets_data.csv')
data['Region'].fillna(X,inplace=True)
print(data.to_string())
使用均值替换某一列的空值
import pandas as pd
data = pd.read_csv('tets_data.csv')
X = data['area'].mean()
data['area'].fillna(X,inplace=True)
print(data.to_string())
清洗格式错误数据
格式化日期
import pandas as pd
# 第三个日期格式错误
data = {
"Date": ['2020/12/01', '2020/12/02' , '20201226'],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
df['Date'] = pd.to_datetime(df['Date'])
print(df.to_string())
Date duration
day1 2020-12-01 50
day2 2020-12-02 40
day3 2020-12-26 45
替换错误数据
import pandas as pd
person = {
"name": ['Google', 'Runoob' , 'Taobao'],
"age": [50, 40, 12345] # 12345 年龄数据是错误的
}
df = pd.DataFrame(person)
df.loc[2, 'age'] = 30 # 修改数据
print(df.to_string())
name age
0 Google 50
1 Runoob 40
2 Taobao 30
设置条件语句
import pandas as pd
person = {
"name": ['Google', 'Runoob' , 'Taobao'],
"age": [50, 200, 12345]
}
df = pd.DataFrame(person)
for x in df.index:
if df.loc[x, "age"] > 120:
df.loc[x, "age"] = 120
print(df.to_string())
name age
0 Google 50
1 Runoob 120
2 Taobao 120
重复数据清洗
如果对应的数据是重复的,**duplicated()**会返回True,否则返回False
import pandas as pd
person = {
"name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
"age": [50, 40, 40, 23]
}
df = pd.DataFrame(person)
print(df.duplicated())
0 False
1 False
2 True
3 False
dtype: bool
删除重复数据
import pandas as pd
persons = {
"name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
"age": [50, 40, 40, 23]
}
df = pd.DataFrame(persons)
df.drop_duplicates(inplace = True)
print(df)
name age
0 Google 50
1 Runoob 40
3 Taobao 23
3 Pandas常用函数
读取数据
函数 | 说明 |
---|---|
pd.read_csv(filename) | 读取 CSV 文件; |
pd.read_excel(filename) | 读取 Excel 文件; |
pd.read_sql(query, connection_object) | 从 SQL 数据库读取数据; |
pd.read_json(json_string) | 从 JSON 字符串中读取数据; |
pd.read_html(url) | 从 HTML 页面中读取数据。 |
实例
import pandas as pd
# 从 CSV 文件中读取数据
df = pd.read_csv('data.csv')
# 从 Excel 文件中读取数据
df = pd.read_excel('data.xlsx')
# 从 SQL 数据库中读取数据
import sqlite3
conn = sqlite3.connect('database.db')
df = pd.read_sql('SELECT * FROM table_name', conn)
# 从 JSON 字符串中读取数据
json_string = '{"name": "John", "age": 30, "city": "New York"}'
df = pd.read_json(json_string)
# 从 HTML 页面中读取数据
url = 'https://www.runoob.com'
dfs = pd.read_html(url)
df = dfs[0] # 选择第一个数据框
查看数据
函数 | 说明 |
---|---|
df.head(n) | 显示前 n 行数据; |
df.tail(n) | 显示后 n 行数据; |
df.info() | 显示数据的信息,包括列名、数据类型、缺失值等; |
df.describe() | 显示数据的基本统计信息,包括均值、方差、最大值、最小值等; |
df.shape | 显示数据的行数和列数。 |
数据清洗
函数 | 说明 |
---|---|
df.dropna() | 删除包含缺失值的行或列; |
df.fillna(value) | 将缺失值替换为指定的值; |
df.replace(old_value, new_value) | 将指定值替换为新值; |
df.duplicated() | 检查是否有重复的数据; |
df.drop_duplicates() | 删除重复的数据。 |
数据选择和切片
函数 | 说明 |
---|---|
df[column_name] | 选择指定的列; |
df.loc[row_index, column_name] | 通过标签选择数据; |
df.iloc[row_index, column_index] | 通过位置选择数据; |
df.ix[row_index, column_name] | 通过标签或位置选择数据; |
df.filter(items=[column_name1, column_name2]) | 选择指定的列; |
df.filter(regex=‘regex’) | 选择列名匹配正则表达式的列; |
df.sample(n) | 随机选择 n 行数据。 |
数据排序
函数 | 说明 |
---|---|
df.sort_values(column_name) | 按照指定列的值排序; |
df.sort_values([column_name1, column_name2], ascending=[True, False]) | 按照多个列的值排序; |
df.sort_index() | 按照索引排序。 |
数据分组和聚合
函数 | 说明 |
---|---|
df.groupby(column_name) | 按照指定列进行分组; |
df.aggregate(function_name) | 对分组后的数据进行聚合操作; |
df.pivot_table(values, index, columns, aggfunc) | 生成透视表。 |
数据合并
函数 | 说明 |
---|---|
pd.concat([df1, df2]) | 将多个数据框按照行或列进行合并; |
pd.merge(df1, df2, on=column_name) | 按照指定列将两个数据框进行合并。 |
数据选择和过滤
函数 | 说明 |
---|---|
df.loc[row_indexer, column_indexer] | 按标签选择行和列。 |
df.iloc[row_indexer, column_indexer] | 按位置选择行和列。 |
df[df[‘column_name’] > value] | 选择列中满足条件的行。 |
df.query(‘column_name > value’) | 使用字符串表达式选择列中满足条件的行。 |
数据统计和描述
函数 | 说明 |
---|---|
df.describe() | 计算基本统计信息,如均值、标准差、最小值、最大值等。 |
df.mean() | 计算每列的平均值。 |
df.median() | 计算每列的中位数。 |
df.mode() | 计算每列的众数。 |
df.count() | 计算每列非缺失值的数量。 |
后续想学习更多数据技能,关注我的公众号哦!