Datawhale学习链接:https://datawhalechina.github.io/joyful-pandas/build/html/%E7%9B%AE%E5%BD%95/ch6.html
【练习题-01】:
将New York的Confirmed, Details, Recovered, Active合并为一张表,索引为如下的日期字符串序列:
[‘04-12-2020’, ‘04-13-2020’, ‘04-14-2020’, ‘04-15-2020’, ‘04-16-2020’]
【我的解答】:
【思考】:
首先看了下数据,一个日期为一个csv文件,即一个日期一张表。其中包含了很多城市,每个城市有很多的指标(Confirmed, Details, Recovered, Active合并等等)。现在的需求是将某一个城市的所在行在所有日期的数据,即将不同表中的某一行合并为一张完整的表。
【解决】:
首先拆解问题,既然是将那么做张表的某一行取出来,那么我首先就看看怎么取表中的某一行。
1、 数据准备,先随便取一张表来做
df1 = pd.read_csv('joyful-pandas-master/data/us_report/04-12-2020.csv')
2、取出New York
的所在行数据
df1.loc[df1['Province_State'] == 'New York']
3、循环遍历文件夹下的文件,取出每张表的New York
的所在行数据。
import os
files = os.walk(r"joyful-pandas-master/data/us_report/")
df_New_York = pd.DataFrame()
for path,dir_list,file_list in files:
for file_name in file_list:
print(file_name)
发现了一个问题!!!循环遍历文件夹取出里面所有文件时,顺序被打乱了。两种解决办法,一是按照日期递增的顺序读取,二是存的时候添加一列来存日期,避免数据与日期匹配错误。(我暂时选第二种)
4、结合第2步与第3步:
import os
files = os.walk(r"joyful-pandas-master/data/us_report/")
df_New_York = pd.DataFrame() # 用来存放最后的结果
for path,dir_list,file_list in files:
for file_name in file_list:
temp = pd.read_csv(file_name) # 用来读取当前的表
temp = temp.loc[temp['Province_State'] == 'New York'].iloc[:,5:9] # 取出对应的行与列
#print(temp)
temp['date'] = file_name.split('.')[0] # 添加日期列,把改行数据对应的日期添加进去
df_New_York = pd.concat([df_New_York, temp]) # 纵向连接终表(df_New_York)与临时表(当前行数据)
temp.drop(temp.index, inplace=True) # 清空临时表的数据,以备下次循环时存储
print(df_New_York)
以上代码会报一个错误:FileNotFoundError: [Errno 2] No such file or directory: '06-07-2020.csv'
。最开始我也很纳闷,读出来的文件名没错,并且文件夹也有该文件,为什么呢?后来才发现上面的temp = pd.read_csv(file_name)
这一句除了问题,只有名字没有路径,当然找不到啦!
解决办法:将那一行修改为以下代码:
temp = pd.read_csv(os.path.join(path, file_name))
5、调整列名顺序,并将日期作为索引
df_New_York = df_New_York[['date','Confirmed','Deaths','Recovered','Active']]
df_New_York.set_index(['date'], inplace=True)
df_New_York
6、现在就需要来解决下日期的顺序问题了。
df_New_York = df_New_York.sort_values(by = 'date')
大功告成啦!!!
整理下这题的答案:
import os
files = os.walk(r"joyful-pandas-master/data/us_report/")
df_New_York = pd.DataFrame() # 用来存放最后的结果
for path,dir_list,file_list in files:
for file_name in file_list:
temp = pd.read_csv(file_name) # 用来读取当前的表
temp = temp.loc[temp['Province_State'] == 'New York'].iloc[:,5:9] # 取出对应的行与列
temp['date'] = file_name.split('.')[0] # 添加日期列,把改行数据对应的日期添加进去
df_New_York = pd.concat([df_New_York, temp]) # 纵向连接终表(df_New_York)与临时表(当前行数据)
temp.drop(temp.index, inplace=True) # 清空临时表的数据,以备下次循环时存储
df_New_York = df_New_York[['date','Confirmed','Deaths','Recovered','Active']]
df_New_York.set_index(['date'], inplace=True)
df_New_York = df_New_York.sort_values(by = 'date')
print(df_New_York)
【补充】:(学到这里,又有一点把前面知识忘记了,这太正常不过啦。不过这个时候就是要用,复习后再使用,印象就会加深了。)
注意:本数据的行索引不是第一列!所以无法通过列名Province_State中的值作为索引来取出某一行。
例如:df1.loc['Florida']
就是错误的!!!
- 取某一行
df1.loc[0] # 取一行的数据(含所有列)
- 选择DataFrame里面某一列等于某个值的所在行,用一条命令即可解决即:
df.loc[df['columnName']=='value']
## 例子,取出Province_State列中值为New York的这一行数据
df1.loc[df1['Province_State'] == 'New York']
- 选出多行多列,一行一列也可以:
法1: 通过列的切片来取
## 取出New York的这一行数据中的Confirmed, Details, Recovered, Active这几列
df1.loc[df1['Province_State'] == 'New York'].iloc[:,5:9]
法2: 通过具体的行名、列名来取:
df.loc[["行名1","行名2"], ["列名1","列名2"]]