1.pandas的Series的一些基础属性
import pandas as pd
# Serise一维数组,DataFrame二维数组
# 创建一维Series
t1 = pd.Series([1,3,5,6,8])
print(t1, '\n')
# 创建一维Series,并修改对应序号
t2 = pd.Series(range(5), index=list("abcde"))
print(t2, '\n')
# 通过字典来创建Series,键为索引,值为值
temp_dict = {'a':1,'b':2,'c':3,'d':4}
t3 = pd.Series(temp_dict)
print(t3, '\n')
"""索引与切片"""
# 只取某个值
print("t3[1]=", t3[1], '\n')
print("t3['a']=", t3['a'], '\n')
# 取连续值
print("t3[:2]=\n",t3[:2], '\n')
print("t3[1:3]=\n", t3[1:3] , '\n')
# 取不连续的多个值
print("t3[[0,2,3]] = \n", t3[[0,2,3]], '\n')
# 在取不连续的多个值时,若索引在Series中没有该值,则输出NAN
# print("t3[['a','f']]=\n", t3[['a','f']], '\n')
# 取Series的键通过index方法
t4 = t3.index
print("t3.index = ", t3.index, '\n')
for i in t4: # 索引index
print(i)
# 将Series的值转成数组
t5 = t3.values
print("t3.value = ", t5, '\n')
print(type(t5), '\n') # 其类型为nampy的数组类型,而numpy中的一些方法也可用于Series,如argmax,clip
2.DataFrame的一些属性和方法
1.df.loc 通过标签索引行数据
2.df.iloc 通过位置获取行数据
3.赋值更改数据的过程:
4.字符串的一些用法
import pandas as pd
import numpy as np
# 读取csv数据
df = pd.read_csv("E:/py_application/mplt_np_pda/dogNames2.csv")
print(df,'\n')
"""
DataFrame对象具有行索引,又有列索引
行索引,表明不同行,横向索引,叫index,0轴,axis = 0
列索引,表明不同例,纵向索引,叫columns,1轴,axis = 1
"""
t1 = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list("defg"))
# index设置行索引,columuns设置列索引
print(t1, '\n')
"""可以用字典,列表等来创建DataFrame"""
"""DataFrame的基础属性"""
print("shape = ", df.shape, '\n')
print("dtypes:\n", df.dtypes, '\n')
print("df.ndim = ", df.ndim, '\n')
print("df.index = ", df.index, '\n')
print("df.columns = ", df.columns, '\n')
print("df.value =\n", df.values, '\n')
"""DataFrame的整体情况查询"""
# 显示头几行,默认5行
print("df.head():\n", df.head(), '\n')
# 显示尾几行,默认5行
print("df.tial():\n", df.tail(), '\n')
# 展示df的概述
print("df.info():\n", df.info(), '\n')
print("df.describe:\n", df.describe(), '\n')
"""DataFrame的排序"""
df1 = df.sort_values(by = "Count_AnimalName",ascending=False )# 参数by是用来指定按谁来排序,这里是按Count_AnimalName来排序,ascending指升序(True)还是降序(False)
print(df1.head(5))
"""pandas取行取列的操作,索引"""
# - 方括号写数组表示取行,对行进行操作
# - 方括号些字符串,表示的取列索引,对列进行操作
print(df[:20], '\n') # 取前20行
print(df["Row_Labels"],'\n') # 取Row_Labels这一列
# df.loc[ ,] 通过 "标签" 索引数据,第一个参数为行,第二个参数为列
print(df.loc[[1,3,9],"Count_AnimalName"], '\n') # 获得1,3,9行的Count_AnimalName列的数据
# df.iloc[ , ]通过 "位置" 获得数据,第一个参数为行,第二个参数为列
print(df.loc[[1,3,9],:], '\n') # 获得1,3,9行的所有列的数据
# pandas 之布尔索引
print(df[(800<df["Count_AnimalName"])&(df["Count_AnimalName"]<1000)]) #取出Count_AnimalName在800到1000之间的数据
3.缺失数据的处理
判断数据是否为NaN:pd.isnull(df),pd.notnull(df)
处理方式1:删除NaN所在的行列dropna (axis=0, how=‘any’, inplace=False)
处理方式2:填充数据,t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)
"""pandas中缺失数据的处理
判断数据是否为NaN:pd.isnull(df),pd.notnull(df)
处理方式1:删除NaN所在的行列dropna (axis=0, how='any', inplace=False)
处理方式2:填充数据,t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)
处理为0的数据:t[t==0]=np.nan
当然并不是每次为0的数据都需要处理
计算平均值等情况,nan是不参与计算的,但是0会
"""
import pandas as pd
import numpy as np
t1 = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list("wxyz"))
print(t1, '\n')
t1["w"]["a"] = np.nan
print(t1, '\n')
print(pd.isnull(t1), '\n')
print(pd.notnull(t1), '\n')
# 删除NaN的所在行或列t1.dropna(axis ,how,inplace)
# axis=0:删除NaN所在行;axis=1:删除NaN所在列
# how ="any":只要有一个NaN就删,how = "all":全部为NaN才删
# inplace表示所作操做是否原地修改,(True)是,反之
t2 = pd.DataFrame(np.arange(12).reshape(3,4),index=list("abc"),columns=list("wxyz"))
t2["w"]["a"] = np.nan
print(t2.dropna(axis=0, how="any", inplace=True))
print("t2:\n", t2)
# 填充NaN处的数据pd.fillna(),在w的NaN处填充w列的均值
print(t1)
t3 = t1["w"].fillna(t1["w"].mean())
print("t1:\n", t3)
4. pandas 中的统计方法
"""pandas 中的统计方法"""
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import font_manager
# 设置字体
my_font = font_manager.FontProperties(fname = "C:/Windows/Fonts/simsun.ttc")
file_path = "E:/py_application/mplt_np_pda/IMDB-Movie-Data.csv"
df = pd.read_csv(file_path)
#print(df.info())
print(df.head(1))
# 获取平均评分
Rating_mean = df["Rating"].mean()
print("平均分:", Rating_mean, '\n')
# 获取导演的人数
Director_num = len(set(df["Director"].tolist()))
# Director_num = len(df["Director"].unique())
print(set(df["Director"].tolist()), '\n')
print("导演人数:", Director_num, '\n')
# 获取演员的人数
temp_actor_list = df["Actors"].str.split(",").tolist()
actor_list = [i for j in temp_actor_list for i in j] # 把列表展开
actor_num = len(set(actor_list))
print("演员的人数", actor_num, '\n')
# 设置图片大小
plt.figure(figsize=(20, 8), dpi=80)
# 画出rating,runtime的分布情况
# 直方图
rating_list = df["Rating"].values
runtime_list = df["Runtime (Minutes)"].values
# print(rating_list, '\n')
# print(runtime_list,'\n')
# 最大最小值
max_rating = rating_list.max()
min_rating = rating_list.min()
dif_rating = max_rating - min_rating +0.1
print("dif_rating", dif_rating, '\n')
max_runtime = runtime_list.max()
min_runtime = runtime_list.min()
dif_runtime = max_runtime - min_runtime
print("dif_runtime",dif_runtime, '\n')
# 组距
num_bin_rating = dif_rating/0.4
num_bin_runtime = dif_runtime//5
"""runtime"""
# 设置x轴
plt.xticks(range(min_runtime, max_runtime+5, 5))
# 画直方图
plt.hist(runtime_list, num_bin_runtime)
# 添加描述信息
plt.xlabel("电影时长",fontproperties = my_font)
plt.ylabel("数量",fontproperties = my_font)
"""rating(ctrl+/,注释或取消注释)"""
# # 设置x轴
# x = [i/2 for i in range(27)]
# print(x)
# plt.xticks(x)
# # 画直方图
# plt.hist(rating_list, int(num_bin_rating))
# # 添加描述信息
# plt.xlabel("电影评分",fontproperties = my_font)
# plt.ylabel("数量",fontproperties = my_font)
# 设置网格
plt.grid()
plt.show()
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib import font_manager
import numpy as np
my_fond = font_manager.FontProperties(fname = "C:/Windows/Fonts/simsun.ttc")
df = pd.read_csv("E:/py_application/mplt_np_pda/IMDB-Movie-Data.csv")
print(df.head(1), '\n')
# 统计分类的情况
temp_list = df["Genre"].str.split(",").tolist()
print(temp_list, '\n')
genre_list = list(set([i for j in temp_list for i in j]))
# 构造全为零的数组
zeros_df = pd.DataFrame(np.zeros((df.shape[0],len(genre_list))),columns=genre_list)
print(zeros_df, '\n')
# 给每个电影位置赋1
for i in range(df.shape[0]):
print(temp_list[i], '\n')
zeros_df.loc[i, temp_list[i]] = 1
print(zeros_df, '\n')
# 每个电影上数量的和
genre_count = zeros_df.sum(axis = 0)
print(genre_count, '\n')
# 排序
genre_count = genre_count.sort_values()
print(genre_count, '\n')
# 画图
plt.figure(figsize=(20,8), dpi=80)
_x = genre_count.index
_y = genre_count.values
plt.bar(_x, _y)
plt.show()
5.分组聚合
1.在pandas中类似的分组的操作我们有很简单的方式来完成
df.groupby(by=“columns_name”)
2.groupby方法之后返回的是一个DataFrameGroupBy对象,是可迭代的
3.grouped中的每一个元素是一个元组,元组里面是(索引(分组的值),分组之后的DataFrame)
4.DataFrameGroupBy对象有很多经过优化的方法
5.获取分组之后的某一部分数据:
df.groupby(by=[“Country”,“State/Province”])[“Country”].count()
6.对某几列数据进行分组:
df[“Country”].groupby(by=[df[“Country”],df[“State/Province”]]).count()
import pandas as pd
import numpy as np
df = pd.read_csv("E:/py_application/mplt_np_pda/starbucks_store_worldwide.csv")
print("df:\n", df, '\n')
print("df.head(1):\n", df.head(1), '\n')
print("df.info():\n", df.info(), '\n')
# 按国家进行分组
grouped = df.groupby(by = "Country")
# 此时的grouped为一个元组,第一个元素为Country的信息,第二个为DataFrame
# grouped中的每一个元素是一个元组,元组里面是(索引(分组的值),分组之后的DataFrame)
print("grouped:\n", grouped, '\n')
print("df:\n", df, '\n')
# grouped的类型为DataFrameGroupBy
# DataFrameGroupBy的公能有
# 1.可以进行遍历
# for i,j in grouped:
# print(i) # i为国家的信息
# print("-"*100)
# print(j) # j为DataFrame的信息
# print("*"*100)
# 取某一个国家的数据的办法
data_US = df[df["Country"] == "US"]
print("data_US:\n", data_US, '\n')
# 2.调用聚合方法
print(grouped.count(), '\n')
country_count = grouped["Brand"].count()
print(country_count["US"], '\n')
print(country_count["CN"], '\n')
# 统计中国每个省份Brand的数量
data_CN = df[df["Country"] == "CN"]
grouped_CN = data_US.groupby(by="State/Province")["Brand"].count()
print("grouped_CN:\n", grouped_CN, '\n')
# 数据按照多个条件分组,返回Series
print(df["Brand"].groupby(by=[df["Country"], df["State/Province"]]).count())
grouped1 = df["Brand"].groupby(by=[df["Country"], df["State/Province"]]).count()
# 数据按照多个条件分组,返DataFrame
print(df[["Brand"]].groupby(by=[df["Country"], df["State/Province"]]).count())
grouped1 = df[["Brand", "Street Address"]].groupby(by=[df["Country"], df["State/Province"]]).count()
grouped2 = df.groupby(by=[df["Country"], df["State/Province"]])[["Brand", "Phone Number"]].count()
print(grouped1, type(grouped1), '\n')
print("-"*100)
print(grouped2, type(grouped2), '\n')
6.索引与复合索引
1简单的索引操作:
获取index:df.index
指定index :df.index = [‘x’,‘y’]
重新设置index : df.reindex(list(“abcedf”))
指定某一列作为index :df.set_index(“Country”,drop=False)
返回index的唯一值:df.set_index(“Country”).index.unique()
import pandas as pd
import numpy as np
df = pd.DataFrame(np.arange(12).reshape(3,4),index=["a", "b", "c"],columns=list("wxzc"))
print("df:\n", df, '\n')
# 获取index
print("df.index", df.index, '\n')
# 指定index
df.index = [1, 2, 3]
print("df.index", df.index, '\n')
print("df:\n", df, '\n')
# 重新设定index
df.index = ["a", "b", "c"]
print("df.reindex[a,c]:\n", df.reindex(["a", "c"]), '\n')
print("df:\n", df, '\n')
# 把某一列作为索引
df1 = df.set_index("w", drop=False) # 把w列作为索引,但不从df中删除w这一列
print("df1:\n", df1, '\n')
df2 = df.set_index("w", drop=True) # 把w列作为索引,并从df中删除w这一列
print("df2:\n", df2, '\n')
# 设置多列索引(复合索引)
df3 = df.set_index(["w","x"])
print("df3:\n", df3, '\n')
df5 = pd.DataFrame({'a': range(7),'b': range(7, 0, -1),'c': ['one','one','one','two','two','two', 'two'],'d': list("hjklmno")})
print("df5:\n", df5, '\n')
df6 = df5.set_index(["c", "d"])
print("df6:\n", df6, '\n')
# 取数据
t = df6["a"] # t为series类型
print(type(t), '\n')
print(t["one"]["k"], '\n')
print(df6.loc["one", "h"], '\n') # 取df6(one, h)
# 交换列索引
df7 = df6.swaplevel()
print("df7:\n", df7, '\n')
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname = "C:/Windows/Fonts/simsun.ttc")
"""使用matplotlib呈现出店铺总数排名前10的国家"""
df = pd.read_csv("E:/py_application/mplt_np_pda/starbucks_store_worldwide.csv")
# print("df:\n", df, '\n')
#
# data1 = df.groupby(by="Country").count()["Brand"].sort_values(ascending=False)[:10]
# print("data1:\n", data1, '\n')
#
# _x = data1.index
# _y = data1.values
#
# # 画图
#
# plt.figure(figsize=(20, 8), dpi=80)
#
# plt.xticks(range(len(_x)), _x)
#
# plt.bar(range(len(_x)), _y)
#
# plt.show()
"""使用matplotlib呈现出每个中国每个城市的店铺数量"""
df1 = df[df["Country"]=="CN"]
print("df1:\n", df1, '\n')
data1 = df1.groupby(by="City").count()["Brand"].sort_values(ascending=False)[:10]
print("data1:\n", data1, '\n')
_x = data1.index
_y = data1.values
# 画图
plt.figure(figsize=(20, 8), dpi=80)
plt.xticks(range(len(_x)), _x , fontproperties=my_font)
plt.bar(range(len(_x)), _y, width=0.3)
plt.show()
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
df = pd.read_csv("E:/py_application/mplt_np_pda/911.csv")
# print("df:\n", df, '\n')
print("df.head(5):\n", df.head(5), '\n')
print("df.info:\n", df.info(), '\n')
# 获取分类
# print(df["title"].str.contains(), '\n')
# print(df["title"].str.split(": ").tolist())
temp_list = df["title"].str.split(": ").tolist()
cater_list = list(set([i[0] for i in temp_list]))
print(cater_list, '\n')
# 构造全为0的数组
zeros_df = pd.DataFrame(np.zeros((df.shape[0], len(cater_list))),columns=cater_list)
# 赋值
for cate in cater_list:
zeros_df[cate][df["title"].str.contains(cate)] = 1
print(zeros_df)
# for i in temp_list:
# zeros_df.loc[i,temp_list[i][0]] = 1
# print(zeros_df)
# 结果
result_sum = zeros_df.sum(axis = 0)
print(result_sum, '\n')
7.时间序列
1.pd.date_range(start=None, end=None, periods=None, freq=‘D’)
start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索引
2.DataFrame中使用时间序列
df[“timeStamp”] = pd.to_datetime(df[“timeStamp”],format="")
format参数大部分情况下可以不用写,但是对于pandas无法格式化的时间字符串,我们可以使用该参数,比如包含中文
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
df = pd.read_csv("E:/py_application/mplt_np_pda/911.csv")
temp_list = df["title"].str.split(": ").tolist()
cater_list = [i[0] for i in temp_list]
cater_df = pd.DataFrame(np.array(cater_list).reshape(df.shape[0],1), columns= ["cate"])
print(cater_df, '\n')
df["cate"] = cater_df
cater_num = df.groupby(by = "cate").count()["title"]
print(cater_num, '\n')
# 把时间字符串转化为时间序列
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
# 把时间序列做为DataFrame的行索引
df.set_index("timeStamp", inplace=True)
# 统计出911数据中不同月份电话次数的和
count_by_moonth = df.resample("M").count()["title"]
print(count_by_moonth, '\n')
_x = count_by_moonth.index
# 格式化时间戳,把时间格式转化成 年-月-日 的格式
_x = [i.strftime("%Y-%m-%d") for i in _x]
print(_x, '\n')
# 画图
plt.figure(figsize=(20,8),dpi=80)
_y = count_by_moonth.values
plt.xticks(range(len(_x)), _x, rotation = 45)
plt.plot(range(len(_x)),_y)
plt.show()
3.重采样
重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样
pandas提供了一个resample的方法来帮助我们实现频率转化
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
df = pd.read_csv("E:/py_application/mplt_np_pda/911.csv")
print(df.head(5))
# 把时间字符串转化成时间类型
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
temp_list = df["title"].str.split(": ").tolist()
cate_list = [i[0] for i in temp_list]
cate_df = pd.DataFrame(np.array(cate_list).reshape(df.shape[0],1),columns=["cate"])
df["cate"] = cate_df
# 把时间字符串转化为索引
df.set_index("timeStamp", inplace=True)
plt.figure(figsize=(20, 8), dpi=80)
for group_name, group_data in df.groupby(by="cate"):
# 统计出911数据中不同月份电话次数的和
count_by_month = group_data.resample("M").count()["title"]
_x = count_by_month.index
_y = count_by_month.values
# 格式化时间格式
_x = [i.strftime("%Y-%m-%d") for i in _x]
plt.plot(range(len(_x)), _y, label=group_name)
plt.xticks(range(len(_x)), _x, rotation=45)
plt.legend(loc="best")
plt.show()
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
df = pd.read_csv("E:/py_application/mplt_np_pda/PM2.5/BeijingPM20100101_20151231.csv")
print("df.info():\n", df.info(), '\n')
print("df.head(5):\n", df.head(5), '\n')
# 把分开的时间字符串通过periodIndex的方法再转化为pandas的时间类型
period = pd.PeriodIndex(year=df["year"], month=df["month"], day=df["day"], freq="H")
print("period:\n", period, '\n')
df["datatime"] = period
# 把datatime设置为索引
df.set_index("datatime", inplace=True)
# 进行降采样
df = df.resample("2M").mean()
# 缺失数据的处理
# print("df[\"PM_US Post\"]:\n", df["PM_US Post"], '\n')
data_us = df["PM_US Post"]
data_cn = df["PM_Dongsihuan"]
# 画图
_x = data_us.index
_y = data_us.values
plt.figure(figsize=(20, 8), dpi=80)
plt.xticks(range(0, len(_x)), list(_x), rotation=45)
plt.plot(range(len(_x)),_y)
plt.show()