前言
numpy可以帮助我们处理数据,同时结合matplotlib解决数据分析的问题,但是numpy只能处理数值型数据,有些时候我们的数据除了数值型数据之外还有字符串、时间序列等,这时候就需要pandas来帮我们处理其他类型的数据了。
一、Pandas简介
如果用 python 的列表和字典来作比较, 那么可以说 Numpy 是列表形式的,没有数值标签,而 Pandas 就是字典形式。Pandas是基于Numpy构建的,让Numpy为中心的应用变得更加简单。
要使用pandas,首先需要了解他主要两个数据结构:Sreies和DataFrame。
Series:一维,带标签数组
DataFrame:二维,是Seris的容器
二、Series基本操作
2.1 Seris创建
创建series过程中可以自定义索引,代码:
import pandas as pd
import numpy as np
import string
#index:索引
a = np.arange(10,20)
b = {string.ascii_lowercase[i]:i for i in range(len(a))}
t = pd.Series(a, index=b)
print(t)
print("*"*10)
#创建一个字典,字典的键对应index
temp_dict = {"name":"xiaoming","age":"18","tel":"11111"}
t1 = pd.Series(temp_dict)
print(t1)
结果:
a ? ?10
b ? ?11
c ? ?12
d ? ?13
e ? ?14
f ? ?15
g ? ?16
h ? ?17
i ? ?18
j ? ?19
dtype: int32
**********
name ? ?xiaoming
age ? ? ? ? ? 18
tel ? ? ? ?11111
dtype: object
pandas中的dtype、astype(更改数据格式)操作与numpy中一样。
2.2 Series切片和索引
切片:之间传入start end或者步长即可
索引:一个的时候直接传入序号或者index,多个时候传入序号或者index的列表
代码:
import pandas as pd
import numpy as np
#index:索引
a = np.arange(10,20)
b = {i for i in range(len(a))}
t = pd.Series(a, index=b)
print(t[2:10:2]) #第三个到第十个每隔一个取一个
print("*"*10)
print(t[1])
print("*"*10)
print(t[[2,3,6]])
print("*"*10)
print(t[t>15])
print("*"*10)
print(t[[0,3]])
对于一个陌生的series类型,对其进行索引和具体值的代码:
import pandas as pd
import numpy as np
import random
import string
#index:索引
a = np.round(np.array([random.random() for i in range(5)]),2)
b = {string.ascii_lowercase[i]:i for i in range(len(a))}
t = pd.Series(a, index=b)
print(t.index) #查看索引
print("*"*10)
print(t.values) #查看数值
2.3 读取外部数据
如果这组数据存在csv中,可以直接使用pd.read_csv进行读取csv中的文件,同时pd.read也可以读取剪切板、excel、html、json等文件。
三、DataFrame基本操作
3.1 创建DataFrame
DataFrame中既有行索引又有列索引
行索引:表明不同行,横向索引,叫index,0轴,axis=0
列索引:表明不同列,纵向索引,叫columns,1轴,axis=1
代码:
import pandas as pd
import numpy as np
import random
import string
a = np.arange(12).reshape(3,4)
a_index = {string.ascii_lowercase[i]:i for i in range((a.shape[0]))}
a_columns = {string.ascii_uppercase[i]:i for i in range((a.shape[1]))}
t = pd.DataFrame(a,index=a_index,columns=a_columns)
print(t)
结果:
A B C D
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
DataFrame是Series的容器,Series可以从字典传入数据,DataFrame同样也可以传入字典。代码:
import pandas as pd
t = {"name":["xiaoming","xiaohong"],"age":[17,18],"tel":[10086,10010]}
print(pd.DataFrame(t))
结果:
name age tel
0 xiaoming 17 10086
1 xiaohong 18 10010
对于DataFrame的基础属性与整体情况可以参照下图方法进行了解:
?3.2 DataFrame索引
此处用到以下csv文件,请大家自行下载
pandas_csv_dog_movie.txt-互联网文档类资源-CSDN下载
链接:https://pan.baidu.com/s/1oUrtw_sedHIC1xQogkaf0A
提取码:6q8y
pandas取行或者列代码:
import pandas as pd
df = pd.read_csv("./dogNames2.csv")
#dataFrame中排序的方法
df = df.sort_values(by="Count_AnimalName",ascending=False)
#pandas取行或者列的注意点
# - 方括号写数组,表示取行,对行进行操作
# - 写字符串,表示的去列索引,对列进行操作
print(df[:5])
print("*"*10)
print(df[:5]["Row_Labels"])#取前5行的Row_Labels这列
print("*"*10)
print(type(df["Row_Labels"]))
3.3 pandas中loc
df.loc:通过标签索引行数据
df.iloc:通过位置获取行数据
df.loc代码:
import pandas as pd
import numpy as np
import string
a = np.arange(12).reshape(3,4)
a_index = {string.ascii_lowercase[i]:i for i in range((a.shape[0]))}
a_columns = {string.ascii_uppercase[i]:i for i in range((a.shape[1]))}
t = pd.DataFrame(a,index=a_index,columns=a_columns)
print(t)
print("*"*10)
print(t.loc["a"])
print("*"*10)
print(t.loc["a","C"])
print("*"*10)
print(t.loc["a",["A","D"]])
print("*"*10)
print(t.loc["b":,"C":])
df.iloc代码:
import pandas as pd
import numpy as np
import string
a = np.arange(12).reshape(3,4)
a_index = {string.ascii_lowercase[i]:i for i in range((a.shape[0]))}
a_columns = {string.ascii_uppercase[i]:i for i in range((a.shape[1]))}
t = pd.DataFrame(a,index=a_index,columns=a_columns)
print(t)
print("*"*10)
print(t.iloc[1,3])
print("*"*10)
print(t.iloc[0:2,3])
print("*"*10)
print(t.iloc[[0,2],2:])
3.3 pandas的布尔索引
回到之前狗的名字的问题上,假如我们想找到所有的使用次数超过800的狗的名字,代码如下:
import pandas as pd
df = pd.read_csv("./dogNames2.csv")
df = df[df["Count_AnimalName"]>800]
print(df)
假如想找到所有的使用次数超过800小于1000的狗的名字,代码如下:
import pandas as pd
df = pd.read_csv("./dogNames2.csv")
df = df[(800<df["Count_AnimalName"])&(df["Count_AnimalName"]<1000)]
print(df)
假如想找到所有的使用次数超过700并且名字的字符串长度大于4的狗的名字,代码如下:
import pandas as pd
df = pd.read_csv("./dogNames2.csv")
df = df[(700<df["Count_AnimalName"])&(df["Row_Labels"].str.len()>4)]
print(df)
pandas字符串用法如下图:
?3.4 缺失数据处理
数据缺失通常有两种情况:
1、空、none等,在pandas中显示为NaN
2、我们让其为0
判断数据是否为NaN:pd.isnull(df),pd.notnull(df)
处理方法一:删除NaN所在的行列dropna(axis=0,how='any',inplace=False)
处理方法二:填充数据,t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)
处理为0的数据:t[t==0]=np.nan
并不是每次为0的数据都需要处理;在计算平均值等情况下NaN不参与计算蚕食0会。
示例:假设我们有一组从2006年到2016年1000部醉流行的电影数据(上面下载链接中有),想知道这些电影数据中评分的平均分、导演的人数等信息,该怎么获取?
代码:
import pandas as pd
import numpy as np
file_path = "IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
#获取平均评分
print(df["Rating"].mean())
#导演的人数
# print(len(set(df["Director"].tolist())))
print(len(df["Director"].unique()))
#获取演员的人数
temp_actors_list = df["Actors"].str.split(", ").tolist()
actors_list = [i for j in temp_actors_list for i in j]
actors_num = len(set(actors_list))
print(actors_num)
对于这些电影数据,如果我们想rating、runtime的分布情况,应该如何呈现数据?
代码:
import pandas as pd
from matplotlib import pyplot as plt
file_path = "IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
#rating runtime分布情况
#选择图形,分布情况:直方图
runtime_data = df["Runtime (Minutes)"].values
df_rating = df["Rating"]
rating_data = df["Rating"].values
max_runtime = runtime_data.max()
min_runtime = runtime_data.min()
max_rating = rating_data.max()
min_rating = rating_data.min()
print(max_runtime-min_runtime)
# print(max_rating-min_rating)
#计算组数
runtime_num_bin = (max_runtime-min_runtime)//5
rating_num_bin_list = [1.6]*12
i=1.6
while i<=max_rating:
i+=0.5
rating_num_bin_list.append(i)
#设置图形大小
plt.figure(figsize=(30,8),dpi=80)
ax1 = plt.subplot(1, 2, 1)
plt.hist(runtime_data,runtime_num_bin)
plt.xticks(range(min_runtime, max_runtime+5, 5))
plt.title("runtime")
ax2 = plt.subplot(1, 2, 2)
plt.hist(rating_data,rating_num_bin_list)
plt.xticks(rating_num_bin_list)
plt.title("rating")
plt.show()
结果:
|