为DataFrame添加一列数据:
In [16]: x = pd.DataFrame(np.arange(12).reshape(3,4),columns=list("QWER"))
In [17]: x
Out[17]:
Q W E R
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
In [18]: x["O"]= pd.DataFrame(np.arange(3).reshape(3,1))
In [19]: x
Out[19]:
Q W E R O
0 0 1 2 3 0
1 4 5 6 7 1
2 8 9 10 11 2
-
现在我们有2015到2017年25万条911的紧急电话的数据,请统计出出这些数据中不同类型的紧急情况的次数,如果我们还想统计出不同月份不同类型紧急电话的次数的变化情况,应该怎么做呢?
-
数据来源:https://www.kaggle.com/mchirico/montcoalert/data
数据格式
lat lng desc zip title timeStamp twp addr e
40.2978759 -75.5812935 REINDEER CT & DEAD END; NEW HANOVER; Station 332; 2015-12-10 @ 17:10:52; 19525 EMS: BACK PAINS/INJURY 2015/12/10 17:10 NEW HANOVER REINDEER CT & DEAD END 1
40.2580614 -75.2646799 BRIAR PATH & WHITEMARSH LN; HATFIELD TOWNSHIP; Station 345; 2015-12-10 @ 17:29:21; 19446 EMS: DIABETIC EMERGENCY 2015/12/10 17:29 HATFIELD TOWNSHIP BRIAR PATH & WHITEMARSH LN 1
代码:
import pandas as pd
import numpy as np
# 准备数据
df = pd.read_csv("./911.csv")
# print(df["title"].head(5))
# print(df.info())
# 提取数据
temp_list = df["title"].str.split(": ").tolist()
# 不同的紧急情况
cate_list = list(set([i[0] for i in temp_list]))
# print(cate_list)
# 构造全为0的数组
zeros_df = pd.DataFrame(np.zeros((df.shape[0],len(cate_list))),columns=cate_list)
# 赋值
for cate in cate_list:
# 利用布尔索引实现一次对一列进行赋值
zeros_df[cate][df["title"].str.contains(cate)] = 1
# print(zeros_df)
# 求和
print(zeros_df.sum(axis=0))
----------------------------------
import pandas as pd
import numpy as np
# 准备数据
df = pd.read_csv("./911.csv")
# print(df["title"].head(5))
# print(df.info())
# 提取数据
temp_list = df["title"].str.split(": ").tolist()
# 不同的紧急情况
cate_list = [i[0] for i in temp_list]
# 添加一列数据
df["cate"] = pd.DataFrame(np.array(cate_list).reshape((df.shape[0],1)))
# 分组统计
print(df.groupby(by="cate").count()["title"])
pandas中的时间序列:
生成一段时间范围:
pd.date_range(start=None, end=None, periods=None, freq='D')
start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索引
In [2]: pd.date_range(start="20191010",end="20201122")
Out[2]:
DatetimeIndex(['2019-10-10', '2019-10-11', '2019-10-12', '2019-10-13',
'2019-10-14', '2019-10-15', '2019-10-16', '2019-10-17',
'2019-10-18', '2019-10-19',
...
'2020-11-13', '2020-11-14', '2020-11-15', '2020-11-16',
'2020-11-17', '2020-11-18', '2020-11-19', '2020-11-20',
'2020-11-21', '2020-11-22'],
dtype='datetime64[ns]', length=410, freq='D')
In [3]: pd.date_range(start="20191010",end="20201122",freq="BM")
Out[3]:
DatetimeIndex(['2019-10-31', '2019-11-29', '2019-12-31', '2020-01-31',
'2020-02-28', '2020-03-31', '2020-04-30', '2020-05-29',
'2020-06-30', '2020-07-31', '2020-08-31', '2020-09-30',
'2020-10-30'],
dtype='datetime64[ns]', freq='BM')
In [4]: pd.date_range(start="20191010",periods=10,freq="WOM-3FRI")
Out[4]:
DatetimeIndex(['2019-10-18', '2019-11-15', '2019-12-20', '2020-01-17',
'2020-02-21', '2020-03-20', '2020-04-17', '2020-05-15',
'2020-06-19', '2020-07-17'],
dtype='datetime64[ns]', freq='WOM-3FRI')
关于频率的更多缩写:
别名 偏移量类型 说明
D Day 每日历日
B BusinessDay 每工作日
H Hour 每小时
T或min Minute 每分
S Second 每秒
L或ms Milli 每毫秒(即每千分之一秒)
U Micro 每微秒(即每百万分之一秒)
M MonthEnd 每月最后一个日历日
BM BusinessMonthEnd 每月最后一个工作日
MS MonthBegin 每月第一个日历日
BMS BusinessMonthBegin 每月第一个工作日
在DataFrame中使用时间序列:
index=pd.date_range("20170101",periods=10)
df = pd.DataFrame(np.random.rand(10),index=index)
回到最开始的911数据的案例中,我们可以使用pandas提供的方法把时间字符串转化为时间序列
df["timeStamp"] = pd.to_datetime(df["timeStamp"],format="")
format参数大部分情况下可以不用写,但是对于pandas无法格式化的时间字符串,我们可以使用该参数,比如包含中文
那么问题来了:
我们现在要统计每个月或者每个季度的次数怎么办呢?
pandas重采样:
重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,
低频率转化为高频率为升采样
pandas提供了一个resample的方法来帮助我们实现频率转化
np.random.uniform(10,50,(100,1))的作用:生成100行1列的10到50之间的随机数二维数组
In [3]: t = pd.DataFrame(np.random.uniform(10,50,(100,1)),index=pd.date_range("20210912",periods=100))
In [4]: t
Out[4]:
0
2021-09-12 48.035949
2021-09-13 10.695941
2021-09-14 40.903627
2021-09-15 19.935708
2021-09-16 35.640888
... ...
2021-12-16 40.102581
2021-12-17 24.833710
2021-12-18 10.483476
2021-12-19 29.515657
2021-12-20 39.668012
In [6]: t.resample("M").mean() # mean取降采样前到降采样后,缺失数据的均值,一般此mean为固定格式
Out[6]:
0
2021-09-30 33.396144
2021-10-31 30.037768
2021-11-30 28.952921
2021-12-31 26.474234
In [7]: t.resample("10D").count()
Out[7]:
0
2021-09-12 10
2021-09-22 10
2021-10-02 10
2021-10-12 10
2021-10-22 10
2021-11-01 10
2021-11-11 10
2021-11-21 10
2021-12-01 10
2021-12-11 10
In [8]: t.resample("QS-JAN").count()
Out[8]:
0
2021-07-01 19
2021-10-01 81
- 统计出911数据中不同月份电话次数的变化情况
- 统计出911数据中不同月份不同类型的电话的次数的变化情况
代码1
import pandas as pd
from matplotlib import pyplot as plt
# 读取数据
df = pd.read_csv("./911.csv")
# 将时间字符串转换成时间序列
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
# 将时间序列设置为索引
df.set_index("timeStamp",inplace=True)
print(df.head())
# 统计出911数据中不同月份电话次数(resample重采样取每个月的数据为一组)
count_by_month = df.resample("M").count()["title"]
print(count_by_month)
# 画图
_x = count_by_month.index
_y = count_by_month.values
# dir产看到当前对象拥有哪些方法
# for i in _x:
# print(dir(i))
# break
_x = [i.strftime("%Y%m%d") for i in _x]
# 图片大小
plt.figure(figsize=(20,8),dpi=80)
# 画折线图
plt.plot(range(len(_x)),_y)
# 画x刻度
plt.xticks(range(len(_x)),_x,rotation=45)
# 显示
plt.show()
效果图:
代码2
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
# 读取数据
df = pd.read_csv("./911.csv")
# 将时间字符串转换成时间序列
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
# 添加列
temp_list = df["title"].str.split(": ").tolist()
cate_list = [i[0] for i in temp_list]
df["cate"] = pd.DataFrame(np.array(cate_list).reshape(df.shape[0],1))
# 将时间序列设置为索引
df.set_index("timeStamp",inplace=True)
# 设置图片大小
plt.figure(figsize=(20,8),dpi=80)
for group_name,group_data in df.groupby(by="cate"):
# 对不同的分类都进行绘图
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)
# 设置x刻度
plt.xticks(range(len(_x)),_x,rotation=45)
# 添加标识信息
plt.legend(loc="best")
# 显示图片
plt.show()
效果图:
-
现在我们有北上广、深圳、和沈阳5个城市空气质量数据,请绘制出5个城市的PM2.5随时间的变化情况
-
观察这组数据中的时间结构,并不是字符串,这个时候我们应该怎么办?
-
数据来源: https://www.kaggle.com/uciml/pm25-data-for-five-chinese-cities
-
之前所学习的DatetimeIndex可以理解为时间戳,那么PeriodIndex可以理解为时间段
-
periods=pd.PeriodIndex(year=data[“year”],month=data[“month”],day=data[“day”],hour=data[“hour”],freq=“H”)
-
那么如果给这个时间段降采样呢?
-
data = df.set_index(periods).resample(“10D”).mean()
-
数据格式:
No year month day hour season PM_Dongsi PM_Dongsihuan PM_Nongzhanguan PM_US Post DEWP HUMI PRES TEMP cbwd Iws precipitation Iprec 1 2010 1 1 0 4 NA NA NA NA -21 43 1021 -11 NW 1.79 0 0 2 2010 1 1 1 4 NA NA NA NA -21 47 1020 -12 NW 4.92 0 0
代码:
import pandas as pd
from matplotlib import pyplot as plt
file_path = "./PM2.5/BeijingPM20100101_20151231.csv"
# 准备数据
df = pd.read_csv(file_path)
# print(df.info())
# 将不同列数据拼凑为时间段
# 把分开的时间字符串通过PeriodIndex的方法转换为pandas的事件类型
period = pd.PeriodIndex(year=df["year"],month=df["month"],day=df["day"],hour=df["hour"],freq="H")
df["datetime"] = period
# print(period)
# print(type(period))
print(df.head(10))
# 把datetime设置为索引,inplace修改原数据
df.set_index("datetime",inplace=True)
# 进行降采样(mean取降采样前到降采样后,缺失数据的均值)
df = df.resample("7D").mean() # DataFrame默认对索引降采样
# 处理(删除)缺失数据
data = df["PM_US Post"]
data_china = df["PM_Dongsi"]
# 画图
_x = data.index
_x_china = [i.strftime("%Y%m%d") for i in data_china.index]
_x = [i.strftime("%Y%m%d") for i in _x]
_y = data.values
_y_china = data_china.values
# 设置图片大小
plt.figure(figsize=(20,8),dpi=80)
# 画折线图
plt.plot(range(len(_x)),_y,label="US_POST")
plt.plot(range(len(_x_china)),_y_china,label="CN_POST")
# 设置x刻度
plt.xticks(range(0,len(_x),10),list(_x)[::10],rotation=45)
plt.legend(loc="best")
# 画图
plt.show()
效果图: