#【Pandas】18 小练习
2023.1.16 两个pandas小练习
18.1 疫情数据分析
18.1.1 观察数据
import pandas as pd
import os
df = pd.read_csv("data/covid19_day_wise.csv")
df
Date | Confirmed | Deaths | Recovered | Active | New cases | New deaths | New recovered | Deaths / 100 Cases | Recovered / 100 Cases | Deaths / 100 Recovered | No. of countries | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2020-01-22 | 555 | 17 | 28 | 510 | 0 | 0 | 0 | 3.06 | 5.05 | 60.71 | 6 |
1 | 2020-01-23 | 654 | 18 | 30 | 606 | 99 | 1 | 2 | 2.75 | 4.59 | 60.00 | 8 |
2 | 2020-01-24 | 941 | 26 | 36 | 879 | 287 | 8 | 6 | 2.76 | 3.83 | 72.22 | 9 |
3 | 2020-01-25 | 1434 | 42 | 39 | 1353 | 493 | 16 | 3 | 2.93 | 2.72 | 107.69 | 11 |
4 | 2020-01-26 | 2118 | 56 | 52 | 2010 | 684 | 14 | 13 | 2.64 | 2.46 | 107.69 | 13 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
183 | 2020-07-23 | 15510481 | 633506 | 8710969 | 6166006 | 282756 | 9966 | 169714 | 4.08 | 56.16 | 7.27 | 187 |
184 | 2020-07-24 | 15791645 | 639650 | 8939705 | 6212290 | 281164 | 6144 | 228736 | 4.05 | 56.61 | 7.16 | 187 |
185 | 2020-07-25 | 16047190 | 644517 | 9158743 | 6243930 | 255545 | 4867 | 219038 | 4.02 | 57.07 | 7.04 | 187 |
186 | 2020-07-26 | 16251796 | 648621 | 9293464 | 6309711 | 204606 | 4104 | 134721 | 3.99 | 57.18 | 6.98 | 187 |
187 | 2020-07-27 | 16480485 | 654036 | 9468087 | 6358362 | 228693 | 5415 | 174623 | 3.97 | 57.45 | 6.91 | 187 |
188 rows × 12 columns
*我的输入错误:readcsv
- 观察一下head
df.head()
Date | Confirmed | Deaths | Recovered | Active | New cases | New deaths | New recovered | Deaths / 100 Cases | Recovered / 100 Cases | Deaths / 100 Recovered | No. of countries | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2020-01-22 | 555 | 17 | 28 | 510 | 0 | 0 | 0 | 3.06 | 5.05 | 60.71 | 6 |
1 | 2020-01-23 | 654 | 18 | 30 | 606 | 99 | 1 | 2 | 2.75 | 4.59 | 60.00 | 8 |
2 | 2020-01-24 | 941 | 26 | 36 | 879 | 287 | 8 | 6 | 2.76 | 3.83 | 72.22 | 9 |
3 | 2020-01-25 | 1434 | 42 | 39 | 1353 | 493 | 16 | 3 | 2.93 | 2.72 | 107.69 | 11 |
4 | 2020-01-26 | 2118 | 56 | 52 | 2010 | 684 | 14 | 13 | 2.64 | 2.46 | 107.69 | 13 |
18.1.2 完成以下数据处理
- 获取 2020 年 2 月 3 日的所有数据
- 2020 年 1 月 24 日之前的累积确诊病例有多少个?
- 2020 年 7 月 23 日的新增死亡数是多少?
- 从 1 月 25 日到 7 月 22 日,一共增长了多少确诊病例?
- 每天新增确诊数和新恢复数的比例?平均比例,标准差各是多少?
- 画图展示新增确诊的变化曲线
- 画图展示死亡率的变化曲线
【练习读取数据】
- 获取 2020 年 2 月 3 日的所有数据
df[df["Date"]=="2020-02-03"]
Date | Confirmed | Deaths | Recovered | Active | New cases | New deaths | New recovered | Deaths / 100 Cases | Recovered / 100 Cases | Deaths / 100 Recovered | No. of countries | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
12 | 2020-02-03 | 19887 | 426 | 604 | 18857 | 3100 | 64 | 145 | 2.14 | 3.04 | 70.53 | 25 |
*注意就是日期格式 0203
- 2020 年 1 月 24 日之前的累积确诊病例有多少个?
我们发现有个Confirmed
通过数字发现应该是之前确诊的
# 方法1
df[df["Date"]=="2020-01-24"]["Confirmed"]
2 941
Name: Confirmed, dtype: int64
# 方法2
df.loc[df["Date"]=="2020-01-24","Confirmed"]
2 941
Name: Confirmed, dtype: int64
*注意和python区别 ,如果用索引查找 要用loc
- 2020 年 7 月 23 日的新增死亡数是多少?
也是读取 NewCaes
df.loc[df["Date"]=="2020-07-23","New deaths"]
183 9966
Name: New deaths, dtype: int64
【时间序列练习】
4. 从 1 月 25 日到 7 月 22 日,一共增长了多少确诊病例?
我们观察这个New cases
是每天的,不是累计,所以要求和
创建成时间序列 就可以计算了 data_range
#创建时间序列
date = pd.to_datetime(df["Date"])
date_range = (date >= "2020-01-25") & (date <= "2020-07-22")
date_range
0 False
1 False
2 False
3 True
4 True
...
183 False
184 False
185 False
186 False
187 False
Name: Date, Length: 188, dtype: bool
new_cases = df.loc[date_range,"New cases" ]
overall = new_cases.sum()
print("共新增:", overall)
共新增: 15247802
我们发现用确诊的相减 和新增加总和是不一致的 分析可能有人重阳了
我们每次提取都是有索引的,所以有时候需要加value
confirmed = df.loc[:, "Confirmed"]
conf_0722 = confirmed.loc[df["Date"] == "2020-07-22"].values
conf_0125 = confirmed.loc[df["Date"] == "2020-01-25"].values
print("格式时代索引的:",confirmed.loc[df["Date"] == "2020-07-22"])
overall2 = conf_0722 - conf_0125
print("共新增:", overall2)
格式时代索引的: 182 15227725
Name: Confirmed, dtype: int64
共新增: [15226291]
【一些计算】
5. 每天新增确诊数和新恢复数的比例?平均比例,标准差各是多少?
per= df["New cases"]/df["New recovered"]
per
0 NaN
1 49.500000
2 47.833333
3 164.333333
4 52.615385
...
183 1.666074
184 1.229207
185 1.166670
186 1.518739
187 1.309638
Length: 188, dtype: float64
【一些值有问题NaN
】
# 有些值是有问题的
per.isna()
0 True
1 False
2 False
3 False
4 False
...
183 False
184 False
185 False
186 False
187 False
Length: 188, dtype: bool
not_zero_per=per[~per.isna()]
ratio_mean = not_zero_per.mean()
ratio_std = not_zero_per.std()
print("平均比例:", ratio_mean, ";标准差:", ratio_std)
平均比例: 7.049556348053247 ;标准差: 19.145284932105497
【联系画图】
- 画图展示新增确诊的变化曲线
df["New cases"].plot()
<AxesSubplot:>
- 画图展示死亡率的变化曲线
df["Deaths / 100 Cases"].plot()
<AxesSubplot:>
18.2 机器学习数据预处理
- 数据导入
- 异常值处理
- 训练集和测试集数据准备
18.2.1 数据导入
import pandas as pd
data=data1 = pd.read_csv("data/iris.csv",names= ["sepal length", "sepal width", "petal length", "petal width", "class"])
data
sepal length | sepal width | petal length | petal width | class | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
... | ... | ... | ... | ... | ... |
145 | 6.7 | 3.0 | 5.2 | 2.3 | Iris-virginica |
146 | 6.3 | 2.5 | 5.0 | 1.9 | Iris-virginica |
147 | 6.5 | 3.0 | 5.2 | 2.0 | Iris-virginica |
148 | 6.2 | 3.4 | 5.4 | 2.3 | Iris-virginica |
149 | 5.9 | 3.0 | 5.1 | 1.8 | Iris-virginica |
150 rows × 5 columns
18.2.2 异常值处理
【NaN】
data.isna()
sepal length | sepal width | petal length | petal width | class | |
---|---|---|---|---|---|
0 | False | False | False | False | False |
1 | False | False | False | False | False |
2 | False | False | False | False | False |
3 | False | False | False | False | False |
4 | False | False | False | False | False |
... | ... | ... | ... | ... | ... |
145 | False | False | False | False | False |
146 | False | False | False | False | False |
147 | False | False | False | False | False |
148 | False | False | False | False | False |
149 | False | False | False | False | False |
150 rows × 5 columns
这种看不出来,用df.isna().any()
查看这一批数据中是否存在空值
df.isna().any()
只要有一个就是’True’
data.isna().any()
sepal length False
sepal width False
petal length False
petal width True
class False
dtype: bool
data.loc[pd.isna(data["petal width"])]
sepal length | sepal width | petal length | petal width | class | |
---|---|---|---|---|---|
25 | 5.0 | 3.0 | 1.6 | NaN | Iris-setosa |
上面找到了Nan值
- 对它进行处理:删掉或者平均
【删掉】
.dropna(axis=0, how="any")
:any
有一个就删除和all
全是删除axis=0
:行方向上变化
data = data.dropna(axis=0, how="any")
data.isna().any()
sepal length False
sepal width False
petal length False
petal width False
class False
dtype: bool
【填充】平均值 填充
- 算平均值
- 把平均值插入到新列中
- 新列赋值到原数据表
data1.isna().any()
sepal length False
sepal width False
petal length False
petal width True
class False
dtype: bool
pepal_width_mean=data1["petal width"].mean()
print(pepal_width_mean)
new_col = data1["petal width"].fillna(pepal_width_mean)
print(new_col)
data1["petal width"]=new_col
data1.isna().any()
1.3946308724832226
0 0.2
1 0.2
2 0.2
3 0.2
4 0.2
...
145 2.3
146 1.9
147 2.0
148 2.3
149 1.8
Name: petal width, Length: 150, dtype: float64
sepal length False
sepal width False
petal length False
petal width False
class False
dtype: bool
- 看值的合理性
不合理的一般去掉 或者 做一些处理
data.plot()
<AxesSubplot:>
data["sepal length"].plot()
<AxesSubplot:>
- 我们发现 这个值小于0是违反常理的 我们可以去掉
.drop()
index=data[data["sepal length"]<0].index
index
data_drop=data.drop(index)
data_drop["sepal length"].plot()
<AxesSubplot:>
或者上一章知识 设定个阈值范围data["sepal length"].clip(lower=0, upper=8)
18.2.3 训练集和测试集
我们假设0.8作为训练集
- 取长度
n = len(data)
150
- 切片:如果我们如果直接切片
tain = data.iloc[:n*0.8]
会报错,因为格式不是整数m
tain_n= int(n*0.8)
tain = data.iloc[:tain_n]
test = data.iloc[tain_n:]
test
sepal length | sepal width | petal length | petal width | class | |
---|---|---|---|---|---|
120 | 6.9 | 3.2 | 5.7 | 2.3 | Iris-virginica |
121 | 5.6 | 2.8 | 4.9 | 2.0 | Iris-virginica |
122 | 7.7 | 2.8 | 6.7 | 2.0 | Iris-virginica |
123 | 6.3 | 2.7 | 4.9 | 1.8 | Iris-virginica |
124 | 6.7 | 3.3 | 5.7 | 2.1 | Iris-virginica |
125 | 7.2 | 3.2 | 6.0 | 1.8 | Iris-virginica |
126 | 6.2 | 2.8 | 4.8 | 1.8 | Iris-virginica |
127 | 6.1 | 3.0 | 4.9 | 1.8 | Iris-virginica |
128 | 6.4 | 2.8 | 5.6 | 2.1 | Iris-virginica |
129 | 7.2 | 3.0 | 5.8 | 1.6 | Iris-virginica |
130 | 7.4 | 2.8 | 6.1 | 1.9 | Iris-virginica |
131 | 7.9 | 3.8 | 6.4 | 2.0 | Iris-virginica |
132 | 6.4 | 2.8 | 5.6 | 2.2 | Iris-virginica |
133 | 6.3 | 2.8 | 5.1 | 1.5 | Iris-virginica |
134 | 6.1 | 2.6 | 5.6 | 1.4 | Iris-virginica |
135 | 7.7 | 3.0 | 6.1 | 2.3 | Iris-virginica |
136 | 6.3 | 3.4 | 5.6 | 2.4 | Iris-virginica |
137 | 6.4 | 3.1 | 5.5 | 1.8 | Iris-virginica |
138 | 6.0 | 3.0 | 4.8 | 1.8 | Iris-virginica |
139 | 6.9 | 3.1 | 5.4 | 2.1 | Iris-virginica |
140 | 6.7 | 3.1 | 5.6 | 2.4 | Iris-virginica |
141 | 6.9 | 3.1 | 5.1 | 2.3 | Iris-virginica |
142 | 5.8 | 2.7 | 5.1 | 1.9 | Iris-virginica |
143 | 6.8 | 3.2 | 5.9 | 2.3 | Iris-virginica |
144 | 6.7 | 3.3 | 5.7 | 2.5 | Iris-virginica |
145 | 6.7 | 3.0 | 5.2 | 2.3 | Iris-virginica |
146 | 6.3 | 2.5 | 5.0 | 1.9 | Iris-virginica |
147 | 6.5 | 3.0 | 5.2 | 2.0 | Iris-virginica |
148 | 6.2 | 3.4 | 5.4 | 2.3 | Iris-virginica |
149 | 5.9 | 3.0 | 5.1 | 1.8 | Iris-virginica |
- 这里面**
class
都相同,我们想打乱顺序。:.sample()
**
data3 = data.sample(frac=1)
tain = data3.iloc[:tain_n]
test = data3.iloc[tain_n:]
test
sepal length | sepal width | petal length | petal width | class | |
---|---|---|---|---|---|
81 | 5.5 | 2.4 | 3.7 | 1.0 | Iris-versicolor |
18 | 5.7 | 3.8 | 1.7 | 0.3 | Iris-setosa |
7 | 5.0 | 3.4 | 1.5 | 0.2 | Iris-setosa |
124 | 6.7 | 3.3 | 5.7 | 2.1 | Iris-virginica |
109 | 7.2 | 3.6 | 6.1 | 2.5 | Iris-virginica |
105 | 7.6 | 3.0 | 6.6 | 2.1 | Iris-virginica |
132 | 6.4 | 2.8 | 5.6 | 2.2 | Iris-virginica |
120 | 6.9 | 3.2 | 5.7 | 2.3 | Iris-virginica |
62 | 6.0 | 2.2 | 4.0 | 1.0 | Iris-versicolor |
15 | 5.7 | 4.4 | 1.5 | 0.4 | Iris-setosa |
93 | 5.0 | 2.3 | 3.3 | 1.0 | Iris-versicolor |
19 | 5.1 | 3.8 | 1.5 | 0.3 | Iris-setosa |
80 | 5.5 | 2.4 | 3.8 | 1.1 | Iris-versicolor |
47 | 4.6 | 3.2 | 1.4 | 0.2 | Iris-setosa |
52 | 6.9 | 3.1 | 4.9 | 1.5 | Iris-versicolor |
70 | 5.9 | 3.2 | 4.8 | 1.8 | Iris-versicolor |
34 | 4.9 | 3.1 | 1.5 | 0.1 | Iris-setosa |
90 | 5.5 | 2.6 | 4.4 | 1.2 | Iris-versicolor |
67 | 5.8 | 2.7 | 4.1 | 1.0 | Iris-versicolor |
45 | 4.8 | 3.0 | 1.4 | 0.3 | Iris-setosa |
40 | 5.0 | 3.5 | 1.3 | 0.3 | Iris-setosa |
54 | 6.5 | 2.8 | 4.6 | 1.5 | Iris-versicolor |
99 | 5.7 | 2.8 | 4.1 | 1.3 | Iris-versicolor |
43 | 5.0 | 3.5 | 1.6 | 0.6 | Iris-setosa |
79 | 5.7 | 2.6 | 3.5 | 1.0 | Iris-versicolor |
83 | 6.0 | 2.7 | 5.1 | 1.6 | Iris-versicolor |
148 | 6.2 | 3.4 | 5.4 | 2.3 | Iris-virginica |
85 | 6.0 | 3.4 | 4.5 | 1.6 | Iris-versicolor |
84 | 5.4 | 3.0 | 4.5 | 1.5 | Iris-versicolor |
96 | 5.7 | 2.9 | 4.2 | 1.3 | Iris-versicolor |
- 切分标签
def get_xy(df):
return df[["sepal length", "sepal width", "petal length", "petal width"]], df[["class"]]
train_x, train_y = get_xy(tain)
test_x, test_y = get_xy(test)
test_y
class | |
---|---|
81 | Iris-versicolor |
18 | Iris-setosa |
7 | Iris-setosa |
124 | Iris-virginica |
109 | Iris-virginica |
105 | Iris-virginica |
132 | Iris-virginica |
120 | Iris-virginica |
62 | Iris-versicolor |
15 | Iris-setosa |
93 | Iris-versicolor |
19 | Iris-setosa |
80 | Iris-versicolor |
47 | Iris-setosa |
52 | Iris-versicolor |
70 | Iris-versicolor |
34 | Iris-setosa |
90 | Iris-versicolor |
67 | Iris-versicolor |
45 | Iris-setosa |
40 | Iris-setosa |
54 | Iris-versicolor |
99 | Iris-versicolor |
43 | Iris-setosa |
79 | Iris-versicolor |
83 | Iris-versicolor |
148 | Iris-virginica |
85 | Iris-versicolor |
84 | Iris-versicolor |
96 | Iris-versicolor |
- DataFrame to Numpy
有的机器学习框架、模型可以直接使用 Pandas 数据类型,有的不一定可以,但是基本上都可以支持 Numpy array。 所以我们还可以进一步将 Pandas 的 DataFrame 转成 Numpy array。
train_x_array, train_y_array = train_x.values, train_y.values
# 前三个实例
print(train_x_array[:3])
print(train_y_array[:3])
[[5.8 2.7 5.1 1.9]
[6.3 2.7 4.9 1.8]
[4.8 3.1 1.6 0.2]]
[['Iris-virginica']
['Iris-virginica']
['Iris-setosa']]