前言
提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。
接 [爱尔兰杀菌剂数据分析_2]
接 爱尔兰杀菌剂数据分析_2
代码非原创,摘抄整理自网络分享
python代码源文件
代码源文件
文章目录
代码
import os # 导入os模块,用于与操作系统交互
import pandas as pd # 导入pandas模块,用于数据处理
# 定义清理函数
def clear():
folder_path = r'C:\Users\admin\Desktop\learn_on_my_own\爱尔兰杀菌剂数据分析\data' # 原始数据文件夹路径
folder_clean_path = r'C:\Users\admin\Desktop\learn_on_my_own\爱尔兰杀菌剂数据分析\data_clean' # 清理后数据文件夹路径
for filename in os.listdir(folder_path): # 遍历原始数据文件夹中的所有文件
if filename.endswith('.xlsx'): # 如果文件是Excel文件
file_path = os.path.join(folder_path, filename) # 构造原始文件的完整路径
file_clean_path = os.path.join(folder_clean_path, filename) # 构造清理后文件的完整路径
df = pd.read_excel(file_path) # 读取Excel文件到DataFrame
# 清理第一列的数据,去除字符串中的空格
df[df.columns[0]] = df[df.columns[0]].apply(lambda x: x.replace(' ', '') if isinstance(x, str) else x)
# 清理列名,去除列名中的空格
df.columns = df.columns.to_series().apply(lambda x: x.replace(' ', '') if isinstance(x, str) else x)
# 选取第一列和不是以'Unnamed:'开头的列,组成新的DataFrame
df = df[df.columns[0]].to_frame().join(df.loc[:, ~df.columns.str.startswith('Unnamed:')])
# 将第一列的列名重命名为空字符串
df.rename(columns={df.columns[0]: ''}, inplace=True)
# 将清理后的DataFrame保存到新的Excel文件
df.to_excel(file_clean_path, index=False)
clear() # 调用清理函数
知识总结
file_path = os.path.join(folder_path, filename)
file_path = os.path.join(folder_path, filename)
具体解释如下:
os.path.join()
:这个函数用于将多个路径组件合并成一个完整的路径。它接受多个字符串参数,每个参数表示路径的一部分,然后将这些部分合并成一个完整的路径。folder_path
:这是一个变量,表示文件夹的路径。filename
:这是一个变量,表示文件的名字。 所以,整个表达式的意思是:将folder_path
表示的文件夹路径和filename
表示的文件名合并成一个完整的文件路径,并存储在file_path
变量中。
这通常用于需要构造完整文件路径的场合,比如读取、写入文件等。通过使用os.path.join
,可以确保不同操作系统之间的路径分隔符正确处理,提高代码的可移植性。
df[df.columns[0]] = df[df.columns[0]].apply(lambda x: …… if else )
df[df.columns[0]] = df[df.columns[0]].apply(lambda x: x.replace(' ', '') if isinstance(x, str) else x)
具体解释如下:
df
:这是一个Pandas DataFrame对象,包含了多列数据。df.columns[0]
:这个表达式表示DataFrame中的第一列的列名。df[df.columns[0]]
:这个表达式表示DataFrame中的第一列的数据。.apply(lambda x: x.replace(' ', '') if isinstance(x, str) else x)
:这个方法用于对第一列的每个元素应用一个函数。这里的函数是一个lambda函数,它检查每个元素:
- 如果元素是字符串类型(
isinstance(x, str)
为真),则使用replace(' ', '')
方法移除字符串中的所有空格。- 如果元素不是字符串类型,则不做任何改变,直接返回原元素。 所以,整个表达式的意思是:对DataFrame中的第一列的每个元素进行检查,如果元素是字符串,则移除其中的所有空格;如果元素不是字符串,则保持不变。这样处理后,第一列中的所有字符串元素都将不再包含空格。
df.columns.to_series()
df.columns.to_series()
是一个用于将 Pandas DataFrame 的列名转换成一个 Pandas
Series 的操作。 下面是对这个操作的详细解释:
df
:表示一个 Pandas DataFrame 对象,它是一个二维的数据结构,包含行和列。df.columns
:这个属性返回 DataFrame 的列名,它是一个类似数组的对象,包含了所有列的名称。.to_series()
:这是一个方法,用于将列名转换成一个 Pandas Series 对象。Series 是 Pandas 中的一维数组型对象,可以存储任何数据类型。 所以,df.columns.to_series()
的意思是将 DataFrame
的列名转换成一个 Series。这个 Series 的索引(index)是列名的位置(从0开始),值是列名的字符串。
df.rename(columns={df.columns[0]: ‘’}, inplace=True)
将DataFrame的第一列的列名重命名为一个空字符串,并且直接在原DataFrame上修改,不创建新的DataFrame对象。
具体解释如下:
df
:表示一个Pandas库中的DataFrame对象,类似于一个二维表格。.rename()
:是DataFrame的一个方法,用于重命名DataFrame的行或列标签。columns={df.columns[0]: ''}
:这是一个字典,用于指定要重命名的列。df.columns[0]
表示DataFrame的第一列的当前列名,''
表示新的列名为一个空字符串。即,将第一列的列名清空。inplace=True
:这是一个布尔值参数,当设置为True
时,表示在原地修改DataFrame,即直接在df
上修改,而不返回一个新的DataFrame对象。
df.to_excel(file_clean_path, index=False)
df.to_excel(file_clean_path, index=False
df
:这通常是一个pandas
库中的DataFrame
对象,代表一个二维的数据表格,类似于电子表格或数据库中的表,包含多行多列的数据。to_excel()
:是pandas
库中DataFrame
类的一个方法,用于将DataFrame
中的数据保存为 Excel 文件。file_clean_path
:这是一个文件路径,指定了生成的 Excel 文件的保存位置。它可以是一个字符串,包含文件的完整路径和文件名(包括.xlsx
后缀),表示将DataFrame
数据保存到该文件中。index=False
:是to_excel()
方法的一个参数,用于控制是否将DataFrame
的索引保存到 Excel 文件中。当index=False
时,不会将索引列添加到 Excel 文件中;如果不指定该参数或设置为
index=True
(默认情况),会将DataFrame
的索引作为第一列添加到生成的 Excel 文件中。
代码
import pandas as pd # 导入pandas模块,用于数据处理
import os # 导入os模块,用于与操作系统交互
# 定义转换函数,将多个excel文件转化为一个excel文件
def trans():
folder_path = r'C:\Users\admin\Desktop\learn_on_my_own\python_Diantou\项目实战\爱尔兰杀菌剂数据分析\data_clean' # 清理后数据文件夹路径
output_path = os.path.join(os.getcwd(), 'output.xlsx') # 输出文件的路径
# 初始化两个列表,用于存储不同类型的数据
data1 = []
data2 = []
for filename in os.listdir(folder_path): # 遍历文件夹中的所有文件
if filename.endswith('.xlsx'): # 如果文件是Excel文件
parts = filename.split('_') # 分割文件名
year = parts[-2] # 获取年份
crop_type = '_'.join(parts[0:-2]) # 获取作物类型
table_type = parts[-1].split('.')[0] # 获取表格类型(ha或ac)
df = pd.read_excel(os.path.join(folder_path, filename), header=0, index_col=0) # 读取Excel文件
for fungicide in df.index: # 遍历杀菌剂
for crop in df.columns: # 遍历作物
value = str(df.loc[fungicide, crop]) # 获取值并转换为字符串
# 处理值,去除逗号,处理小于号,尝试转换为浮点数
if isinstance(value, str):
value = value.replace(',', '').split(".")[0].replace('<', '0.')
try:
value = float(value)
except ValueError:
value = 0.0
else:
print(value) # 如果值不是字符串,打印值
break # 并跳出循环
# 如果值不是空值
if pd.notna(value):
# 根据表格类型将数据添加到相应的列表
if table_type == 'ha':
data1.append([year, crop_type, crop, fungicide, value])
elif table_type == 'ac':
data2.append([year, crop_type, crop, fungicide, value])
# 打印两个列表的内容
print(data1)
print(data2)
# 将列表转换为DataFrame
df_data1 = pd.DataFrame(data1, columns=['Year', 'Crop Type', 'Crop', 'Fungicide', 'Hectares'])
df_data2 = pd.DataFrame(data2, columns=['Year', 'Crop Type', 'Crop', 'Fungicide', 'Active Substance'])
# 合并两个DataFrame
df_data = pd.merge(df_data1, df_data2, how='inner', on=['Year', 'Crop Type', 'Crop', 'Fungicide'])
# 将合并后的DataFrame保存到Excel文件
df_data.to_excel(output_path, index=False)
trans() # 调用转换函数
# 读取输出的Excel文件并显示前几行
df = pd.read_excel(r'C:\Users\admin\Desktop\learn_on_my_own\python_Diantou\项目实战\爱尔兰杀菌剂数据分析\output.xlsx')
df.head()
运行结果
pd.merge(df_data1, df_data2, how=‘inner’, on=[‘Year’, ‘Crop Type’, ‘Crop’, ‘Fungicide’])
这段代码是使用Pandas库中的
merge
函数来合并两个DataFrame对象df_data1
和df_data2
。下面是对这段代码的详细解释:
pd
:这是Pandas库的常用别名。在使用这段代码之前,通常需要先导入Pandas库,例如使用import pandas as pd
。merge
:这是Pandas库中的一个函数,用于根据一个或多个键将两个DataFrame合并在一起。df_data1
:第一个要合并的DataFrame对象。df_data2
:第二个要合并的DataFrame对象。how='inner'
:这个参数指定了合并的方式。'inner'
表示内连接,即只有当键(在这里是Year
、Crop Type
、Crop
和Fungicide
)在两个DataFrame中都存在时,相应的行才会被包含在结果中。其他常见的合并方式包括'outer'
(外连接)、'left'
(左连接)和'right'
(右连接)。on=['Year', 'Crop Type', 'Crop', 'Fungicide']
:这个参数指定了合并的键,即根据哪些列的值来合并DataFrame。在这个例子中,合并是基于Year
、Crop Type
、Crop
和Fungicide
这四列的值。
整体意思: 这段代码将df_data1
和df_data2
这两个DataFrame根据Year
、Crop Type
、Crop
和Fungicide
这四列的值进行内连接合并。只有当这些列的值在两个DataFrame中都相同时,相应的行才会被包含在合并后的DataFrame中。
代码
# 删除包含缺失值的行,特别是'Fungicide'列中的缺失值
df.dropna(subset=['Fungicide'], inplace=True)
# 打印清洗前的数据数量
print(f'清洗前,数据的数量:{len(df)}')
# 将'Fungicide'列中包含不同大小写形式的'OtherFungicides'的值统一替换为'Other Fungicide'
df.loc[df['Fungicide'].str.contains('OtherFungicides', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('OtherFungicide', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('Other Fungicides', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('Other Fungicide', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('otherFungicides', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('otherFungicide', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('other Fungicides', case=False), 'Fungicide'] = 'Other Fungicide'
df.loc[df['Fungicide'].str.contains('other Fungicide', case=False), 'Fungicide'] = 'Other Fungicide'
# 将'Fungicide'列中包含不同大小写形式的'AllFungicides'的值统一替换为'all Fungicide'
df.loc[df['Fungicide'].str.contains('AllFungicides', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('AllFungicide', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('All Fungicides', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('All Fungicide', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('allFungicides', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('allFungicide', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('all Fungicides', case=False), 'Fungicide'] = 'all Fungicide'
df.loc[df['Fungicide'].str.contains('all Fungicide', case=False), 'Fungicide'] = 'all Fungicide'
# 从数据中排除'Fungicide'列包含'Other Fungicide'或'all Fungicide'的行
df = df[~df['Fungicide'].str.contains('Other Fungicide|all Fungicide', case=False)]
# 从数据中排除'Crop'列包含特定关键词的行,这些关键词表示总数量或总面积等汇总数据
df = df[~df['Crop'].str.contains('Allcrops|Allcrops\\(spha\\)|Allcrops\\(kg\\)|Totalquantity\\(kg\\)|Totalarea\\(spha\\)|Totalquantity|Totalarea', case=False, regex=True)]
# 打印清洗后的数据数量
print(f'清洗后的数据数量:{len(df)}')
df.dropna(subset=[‘Fungicide’], inplace=True)
这段代码是使用Pandas库中的
dropna
方法来处理DataFrame中的缺失值。下面是对这段代码的详细解释:
df
:这是要处理的DataFrame对象。dropna
:这是Pandas库中DataFrame对象的一个方法,用于删除包含缺失值的行或列。subset=['Fungicide']
:这个参数指定了只考虑某些列的缺失值。在这个例子中,只有'Fungicide'
这一列的缺失值会被考虑。如果一行中的'Fungicide'
列是缺失值(NaN),那么这一行就会被删除。inplace=True
:这个参数指定了是否在原地修改DataFrame。True
表示直接在原DataFrame上删除含有缺失值的行,而不返回一个新的DataFrame。如果设置为False
(默认值),则返回一个新的DataFrame,原DataFrame不变。
整体意思: 这段代码会删除df
中'Fungicide'
列含有缺失值的所有行,并且直接在原DataFrame上进行修改,不会返回一个新的DataFrame。
df.loc[]
df.loc[]
是Pandas库中DataFrame对象的一个属性,用于通过标签(即列名和行索引)来访问和修改数据。loc[]
后面跟着的是方括号,用于指定要访问或修改的数据的位置。
loc[]
可以用于以下几种情况:
- 选择单行或单列:
df.loc['row_label']
:选择行标签为’row_label’的行。df.loc[:, 'column_label']
:选择列标签为’column_label’的列。- 选择多行或多列:
df.loc[['row1', 'row2']]
:选择行标签为’row1’和’row2’的行。df.loc[:, ['col1', 'col2']]
:选择列标签为’col1’和’col2’的列。- 选择特定的单元格:
df.loc['row_label', 'column_label']
:选择行标签为’row_label’,列标签为’column_label’的单元格。- 使用条件表达式:
df.loc[df['column'] > 0]
:选择列’column’中值大于0的行。- 赋值操作:
df.loc['row_label', 'column_label'] = new_value
:将行标签为’row_label’,列标签为’column_label’的单元格的值设置为new_value。- 切片操作:
df.loc['row_start':'row_end', 'col_start':'col_end']
:选择从’row_start’到’row_end’的行,以及从’col_start’到’col_end’的列。
df.iloc[]
df.iloc[]
是 Pandas
中的一种数据选择方法,它允许用户基于整数位置(即行号和列号)来选择数据。这种方法在处理大型数据集时非常有用,因为它允许用户快速定位到特定的行和列。以下是
df.iloc[]
的详细介绍:
基本语法
df.iloc[行选择器, 列选择器]
- 行选择器 和 列选择器 可以是整数、列表、切片或布尔数组。
使用示例
假设有一个简单的 DataFramedf
:
import pandas as pd
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df = pd.DataFrame(data)
1. 选择单行
# 选择第一行
print(df.iloc[0])
输出:
A 1
B 4
C 7
Name: 0, dtype: int64
2. 选择单列
# 选择第一列
print(df.iloc[:, 0])
输出:
0 1
1 2
2 3
Name: A, dtype: int64
3. 选择多个行
# 选择第一行和第三行
print(df.iloc[[0, 2]])
输出:
A B C
0 1 4 7
2 3 6 9
4. 选择多个列
# 选择第一列和第三列
print(df.iloc[:, [0, 2]])
输出:
A C
0 1 7
1 2 8
2 3 9
5. 选择特定的单元格
# 选择第一行第一列的单元格
print(df.iloc[0, 0])
输出:
1
6. 切片操作
# 选择前两行和前两列的部分DataFrame
print(df.iloc[0:2, 0:2])
输出:
A B
0 1 4
1 2 5
7. 布尔索引
# 选择所有行的第一列,其中值大于1
print(df.iloc[df.iloc[:, 0] > 1, 0])
输出:
1 2
2 3
Name: A, dtype: int64
注意事项
df.iloc[]
的索引是从0开始的,这与 Python 的列表索引方式一致。- 当使用切片时,
df.iloc[]
是inclusive的,即包括起始和结束索引。df.iloc[]
不能用于设置新的列或行,只能用于选择现有的数据。
与df.loc[]
的区别df.loc[]
基于标签进行数据选择,而df.iloc[]
基于整数位置进行数据选择。df.loc[]
可以使用列名和行索引,而df.iloc[]
只能使用行号和列号。
总结
df.iloc[]
是 Pandas 中一种强大且灵活的数据选择方法,特别适用于基于整数位置进行快速数据访问和操作。通过结合不同的选择器,可以实现对数据的精细控制,从而提高数据分析和处理的效率。
代码
# 将名称包含Arable的值重命名为Arable_crops
df.loc[df['Crop Type'].str.contains('Arable', case=False), 'Crop Type'] = 'Arable_crops'
df.loc[df['Crop Type'].str.contains('Grassland|Grassl', case=False), 'Crop Type'] = 'Grassland_fodder_crops'
df.loc[df['Crop Type'].str.contains('Protected', case=False), 'Crop Type'] = 'Protected_crops'
df.loc[df['Crop Type'].str.contains('Soft', case=False), 'Crop Type'] = 'Soft_fruit'
df.loc[df['Crop Type'].str.contains('Top', case=False), 'Crop Type'] = 'Top_soft_fruit'
df.loc[df['Crop Type'].str.contains('vegetable', case=False), 'Crop Type'] = 'Outdoor_vegetable_crops'
df['Crop Type'].unique()
运行结果
df[‘Crop Type’].unique()
df['Crop Type'].unique()
是 Pandas 中的一种方法,用于获取 DataFramedf
中 ‘Crop
Type’ 列的所有唯一值。下面是对这个方法的详细解释: 解释
df
:表示一个 Pandas DataFrame,即数据框,它是一个二维的表格型数据结构。['Crop Type']
:这是对 DataFrame 的列进行选择的方式,表示选择名为 ‘Crop Type’ 的列。.unique()
:这是一个 Pandas 方法,用于返回指定列中的所有唯一值,即去除重复值后剩下的值。
功能- 获取唯一值:这个方法会遍历 ‘Crop Type’ 列中的所有值,然后返回一个包含所有不同值的数组,每个值只出现一次。
- 去重:如果 ‘Crop Type’ 列中有重复的值,
.unique()
方法会自动去除这些重复值,只保留唯一的值。
代码
# 按照不同的值,将data分成不同的数据集
data1=df[df["Crop Type"]=="Arable_crops"].to_excel("temp_data_IR/Arable_crops.xlsx")
data2=df[df["Crop Type"]=="Protected_crops"].to_excel("temp_data_IR/Protected_crops.xlsx")
data3=df[df["Crop Type"]=="Grassland_fodder_crops"].to_excel("temp_data_IR/Grassland_fodder_crops.xlsx")
data4=df[df["Crop Type"]=="Outdoor_vegetable_crops"].to_excel("temp_data_IR/Outdoor_vegetable_crops.xlsx")
data8=df[df["Crop Type"]=="Top_soft_fruit"].to_excel("temp_data_IR/Top_soft_fruit.xlsx")
data9=df[df["Crop Type"]=="Soft_fruit"].to_excel("temp_data_IR/Soft_fruit.xlsx")