public.py 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. import pandas as pd
  2. import numpy as np
  3. # 这里写所有表格的判断规则 按顺序每个表格一个函数 方便后续修改
  4. pd.set_option('display.max_columns', 1000)
  5. pd.set_option('display.width', 1000)
  6. pd.set_option('display.max_colwidth', 1000)
  7. # 表1 土壤容重机械组成数据 为了方便做具体修改
  8. def soil_bulk_density(arr): #arr为计算过的数组
  9. # (1)土壤容重不在[0.8, 1.6]范围以内的,存疑
  10. shenHeList=[] # 定义一个数组存放容重存疑的数据
  11. shenHeTarget = [] # 存放每条数据 有问题的指标
  12. try:
  13. for i in arr['土壤容重平均值(g/cm3)(计算)']:
  14. if i > 1.6 or i < 0.8:
  15. shenHeList.append('土壤容重:复核数据合理性。')
  16. shenHeTarget.append('土壤容重平均值。')
  17. else:
  18. shenHeList.append('')
  19. shenHeTarget.append('')
  20. except Exception as err:
  21. print('土壤容重判断出错!请检查soil_bulk_density中判断土壤容重内容',err)
  22. # (2)土壤利用类型→耕地、园地→相对极差>15 %,存疑;土壤利用类型→林地、草地→相对极差>20 %,存疑
  23. tRTypeList = [] # 定义一个数组存放土壤利用类型存疑的数据
  24. tRTypeTarget= [] # 定义一个数组存放土壤利用类型存疑的数据指标名称
  25. try:
  26. for i in arr['相对极差(%)']:
  27. # TODO 此处土地利用类型应从原样品编码提取7-8位两位数组,01代表耕地,02代表园地,03代表林地,04代表草地
  28. if i > 15 and arr.loc[arr['相对极差(%)'] == i, '土地利用类型'].iloc[0] == '耕地园地':
  29. tRTypeList.append('存疑:耕地园地相对极差>15%。')
  30. tRTypeTarget.append('耕地园地极差。')
  31. elif i > 20 and arr.loc[arr['相对极差(%)'] == i, '土地利用类型'].iloc[0] == '林地草地':
  32. tRTypeList.append('存疑:林地草地相对极差>20%。')
  33. tRTypeTarget.append('林地草地极差。')
  34. else:
  35. tRTypeList.append('')
  36. tRTypeTarget.append('')
  37. except Exception as err:
  38. print('相对极差判断、土壤利用类型判断出错!请检查soil_bulk_density中判断相对极差判断、土壤利用类型内容',err)
  39. # (3)加和不在[99.98, 100.02]范围内的,存疑
  40. plusShenHeList = [] # 定义一个数组存放加和存疑的数据
  41. plusShenHeTarget = [] # 保存土壤颗粒加和存疑的指标
  42. try:
  43. for i in arr['加和%']:
  44. if float(i) > 100.02 or float(i) < 99.98:
  45. plusShenHeList.append('土壤颗粒加和:复核数据合理性。')
  46. plusShenHeTarget.append('土壤颗粒含量加和。')
  47. else:
  48. plusShenHeList.append('')
  49. plusShenHeTarget.append('')
  50. except Exception as err:
  51. print('颗粒含量加和判断出错!请检查soil_bulk_density中判断颗粒含量加和内容',err)
  52. # 根据国际土壤质地类型三角形编程实现对质地的分类→判断质地分类和质地名称是否正确
  53. # 判断土壤类型逻辑:
  54. soilList = [] # 定义一个数组存放土地类型的数据
  55. soilContent = []
  56. soilContentTarget = [] # 存放土壤质地异常的指标名称
  57. xSLErr = [] # 存放ph>7 洗失量为空的异常数据
  58. xSLTarget = [] # 存放异常数据 指标名称
  59. try:
  60. # 按行循环读取所有数据
  61. for index, row in arr.iterrows():
  62. # 1.将0.02-0.2,0.2-2两列加起来
  63. plusSoil = row['0.2-0.02mm颗粒含量%'] + row['2-0.2mm颗粒含量%']
  64. small_002_list = row['0.02-0.002mm颗粒含量%']
  65. small_0002_list = row['0.002mm以下颗粒含量%']
  66. if np.isnan(plusSoil) or np.isnan(small_002_list) or np.isnan(small_0002_list):
  67. soilList.append('')
  68. # 具体判断 这里为了方便看 减少了嵌套逻辑
  69. elif small_0002_list >=65 and small_0002_list <100: # 2. <0.002含量 65-100 ->重黏土
  70. soilList.append('重黏土')
  71. elif small_0002_list >= 45 and small_0002_list <65: # 3.<0.002含量 45-65 ->黏土
  72. soilList.append('黏土')
  73. elif small_0002_list >= 25 and small_0002_list <45 and small_002_list >= 45 and small_002_list <75: # 4. <0.002含量 25-45 and 0.002-0.02含量 45-75 -> 粉(砂)质黏土
  74. soilList.append('粉(砂)质黏土')
  75. elif small_0002_list >= 25 and small_0002_list<45 and small_002_list>=0 and small_002_list<45 and plusSoil>=10 and plusSoil <55: # 5. <0.002含量 25-45 and 0.002-0.02含量 0-45 and 0.02-2含量 10-55-> 壤质黏土
  76. soilList.append('壤质黏土')
  77. elif small_0002_list >= 25 and small_0002_list<45 and small_002_list>=0 and small_002_list<20 and plusSoil>=55 and plusSoil <75:# 6. <0.002含量 25-45 and 0.002-0.02含量 0-20 and 0.02-2含量 55-75-> 砂质黏土
  78. soilList.append('砂质黏土')
  79. elif small_0002_list >= 15 and small_0002_list<25 and small_002_list>=45 and small_002_list<85: # 7.<0.002含量 15-25 and 0.002-0.02含量 45-85 -> 粉(砂)质黏壤土
  80. soilList.append('粉(砂)质黏壤土')
  81. elif small_0002_list >= 15 and small_0002_list<25 and small_002_list>=20 and small_002_list<45 and plusSoil>=30 and plusSoil <55:# 8.<0.002含量 15-25 and 0.002-0.02含量 20-45 and 0.02-2含量 30-55-> 黏壤土
  82. soilList.append('黏壤土')
  83. elif small_0002_list >= 15 and small_0002_list<25 and small_002_list>=0 and small_002_list<30 and plusSoil>=55 and plusSoil <85:# 9.<0.002含量 15-25 and 0.002-0.02含量 0-30 and 0.02-2含量 55-85-> 砂质黏壤土
  84. soilList.append('砂质黏壤土')
  85. elif small_0002_list >= 0 and small_0002_list<15 and small_002_list>=45 and small_002_list<100:#10.<0.002含量 0-15 and 0.002-0.02含量 45-100 ->粉(砂)质壤土
  86. soilList.append('粉(砂)质壤土')
  87. elif small_0002_list >= 0 and small_0002_list<15 and small_002_list>=30 and small_002_list<45 and plusSoil>=40 and plusSoil <55: # 11.<0.002含量 0-15 and 0.002-0.02含量 30-45 and 0.02-2含量 40-55-> 壤土
  88. soilList.append('壤土')
  89. elif small_0002_list >= 0 and small_0002_list<15 and small_002_list>=0 and small_002_list<45 and plusSoil>=55 and plusSoil <85: # 12.<0.002含量 0-15 and 0.002-0.02含量 0-45 and 0.02-2含量 55-85-> 砂质壤土
  90. soilList.append('砂质壤土')
  91. elif small_0002_list >= 0 and small_0002_list<15 and small_002_list>=0 and small_002_list<15 and plusSoil>=85 and plusSoil <100: # 13.<0.002含量 0-15 and 0.002-0.02含量 0-15 and 0.02-2含量 85-100-> 砂土及壤质砂土
  92. soilList.append('砂土及壤质砂土')
  93. else:
  94. soilList.append('') # 除所有情况外 还有空值
  95. # 比较和原有数据是否一致
  96. arr['土壤质地(判断)'] = soilList
  97. for index, row in arr.iterrows():
  98. if (row['土壤质地(判断)'] != row['土壤质地']) and (not pd.isna(row['土壤质地'])):
  99. soilContent.append('存疑:土壤质地填报与判断不一致')
  100. soilContentTarget.append('土壤质地。')
  101. else:
  102. soilContent.append('')
  103. soilContentTarget.append('')
  104. # 如果pH>7,则洗失量数据不能为空;
  105. if (not pd.isna(row['pH']) and row['pH'] > 7 and pd.isna(row['洗失量(吸管法需填)%'])):
  106. xSLErr.append('洗失量:ph>7但洗失量未检测。')
  107. xSLTarget.append('洗失量。')
  108. else:
  109. xSLErr.append('')
  110. xSLTarget.append('')
  111. except Exception as err:
  112. print('土壤类型判断出错!请检查soil_bulk_density中判断土壤类型内容', err)
  113. # 把存疑数据组合并返回
  114. # print('shenHeList--',shenHeList,len(shenHeList))
  115. # print('plusShenHeList--', plusShenHeList, len(plusShenHeList))
  116. # print('tRTypeList--', tRTypeList, len(tRTypeList))
  117. # print('soilContent--', soilContent, len(soilContent))
  118. # print('soilList--', soilList, len(soilList))
  119. pdData = pd.DataFrame({
  120. '审核结果': pd.Series(shenHeList) + pd.Series(tRTypeList) + pd.Series(plusShenHeList) + pd.Series(soilContent) + pd.Series(xSLErr),
  121. '土壤质地(判断)': soilList,
  122. '异常指标': pd.Series(shenHeTarget) + pd.Series(tRTypeTarget) + pd.Series(plusShenHeTarget) + pd.Series(soilContentTarget) + pd.Series(xSLTarget),
  123. })
  124. return pdData
  125. # 这是一个判断范围的函数 如果需要修改范围 修改start end值就行
  126. def is_not_in_range(value):
  127. return value <30 or value > 90
  128. # 表3 水稳性大团聚体规则判断函数
  129. def water_stable(arr):
  130. # (1)不在[30, 90]范围以内的,存疑
  131. shenHeList = [] # 定义一个数组存放团聚体存疑的数据
  132. shenHeTar = [] # 存放水稳异常指标
  133. # (2)总和超过90,存疑;耕地和园地>80,提示关注;林地和草地>90,提示关注
  134. plusList = []
  135. plusTar = [] # 水稳总和异常指标名称
  136. soilType = []
  137. # (3)>5mm指标占比超过10 %,存疑,应回溯
  138. rateList = []
  139. rateTar = [] # >5mm占比异常指标
  140. try:
  141. for index, row in arr.iterrows():
  142. # 规则1判断 先判断值是否存在
  143. # if (not pd.isna(row['>5mm%']) and is_not_in_range(row['>5mm%'])) or (
  144. # not pd.isna(row['3-5mm%']) and is_not_in_range(row['3-5mm%'])) or (
  145. # not pd.isna(row['2-3mm%']) and is_not_in_range(row['2-3mm%'])) or (
  146. # not pd.isna(row['1-2mm%']) and is_not_in_range(row['1-2mm%'])) or (
  147. # not pd.isna(row['0.5-1mm%']) and is_not_in_range(row['0.5-1mm%'])) or (
  148. # not pd.isna(row['0.25-0.5mm%']) and is_not_in_range(row['0.25-0.5mm%'])):
  149. # shenHeList.append('存疑:团聚体百分比不在范围以内。')
  150. # shenHeTar.append('水稳分项指标。')
  151. # else:
  152. # shenHeList.append('')
  153. # shenHeTar.append('')
  154. # 规则2判断
  155. if row['总和(%)'] > 60 or row['总和(%)'] < 1:
  156. plusList.append('水稳性大团聚体:总和复核数据合理性。')
  157. plusTar.append('水稳总和。')
  158. else:
  159. plusList.append('')
  160. plusTar.append('')
  161. if (row['土地利用类型'] == '耕地园地' and row['总和(%)'] > 80) or (row['土地利用类型'] == '林地草地' and row['总和(%)'] > 90):
  162. soilType.append('关注:耕地园地团聚体总和大于80或林地草地团聚体总和大于90。')
  163. else:
  164. soilType.append('')
  165. if row['>5mm%'] > 10:
  166. rateList.append('存疑:>5mm占比超过10%应回溯。')
  167. rateTar.append('水稳>5mm。')
  168. else:
  169. rateList.append('')
  170. rateTar.append('')
  171. resData = pd.DataFrame({
  172. '审核结果': pd.Series(plusList) + pd.Series(soilType) + pd.Series(rateList),
  173. '异常指标': pd.Series(plusTar) + pd.Series(rateTar),
  174. })
  175. return resData
  176. except Exception as err:
  177. print('大团聚体判断出错!请检查water_stable中判断大团聚体内容', err)
  178. # 表5 pH、阳离子交换量、交换性盐基基础数据判断
  179. # 判断土壤类型和阳离子交换量 盐基饱和度的范围
  180. def soilTypeValue(row): # 传入一行数据
  181. strValue = row['土壤类型']
  182. soilType = ''
  183. if isinstance(strValue, str):
  184. # print('type---', strValue.split('_'))
  185. # print('strValue',strValue)
  186. if len(strValue.split('_')) > 1:
  187. soilType = strValue.split('_')[1] # 获取到土壤类型
  188. cationChange = row['阳离子交换量Cmol(+)/kg'] # 获取到阳离子交换量
  189. bHValue = (row['交换性盐总量Cmol(+)/kg']/row['阳离子交换量Cmol(+)/kg'] )*100# 计算出的盐基饱和度
  190. # 判断三者范围是否合理
  191. res = ''
  192. if soilType == '黄红壤':
  193. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange<24) and (not pd.isna(bHValue)) and (bHValue > 30 and bHValue<50):
  194. res = ''
  195. else:
  196. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  197. elif soilType == '棕红壤':
  198. if (not pd.isna(cationChange)) and (cationChange > 6 and cationChange < 15) and (not pd.isna(bHValue)) and (
  199. bHValue > 25 and bHValue < 70):
  200. res = ''
  201. else:
  202. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  203. elif soilType == '红壤性土':
  204. if (not pd.isna(cationChange)) and (cationChange > 5 and cationChange < 15) and (not pd.isna(bHValue)) and (
  205. bHValue > 10 and bHValue < 50):
  206. res = ''
  207. else:
  208. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  209. elif soilType == '典型黄壤':
  210. if (not pd.isna(cationChange)) and (cationChange > 5 and cationChange < 15) and not(pd.isna(bHValue)) and (
  211. bHValue < 30):
  212. res = ''
  213. else:
  214. res = '该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  215. elif soilType == '黄壤性土':
  216. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 18) and (not pd.isna(bHValue)) and (
  217. bHValue < 45):
  218. res = ''
  219. else:
  220. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  221. elif soilType == '典型黄棕壤' or soilType == '暗黄棕壤' or soilType == '黄棕壤性土':
  222. if (not pd.isna(cationChange)) and (cationChange > 8 and cationChange < 22) and (not pd.isna(bHValue)) and (
  223. bHValue > 30 and bHValue < 60):
  224. res = ''
  225. else:
  226. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  227. elif soilType == '典型黄褐土' or soilType == '黏盘黄褐土' or soilType == '粘盘黄褐土' or soilType == '粘盘黄褐土' or soilType=='白浆化黄褐土' or soilType=='黄褐土性土':
  228. if (not pd.isna(cationChange)) and (cationChange > 15 and cationChange < 25) and (not pd.isna(bHValue)) and (
  229. bHValue > 60 and bHValue < 85):
  230. res = ''
  231. else:
  232. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  233. elif soilType == '粘盘黄褐土':
  234. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 30) and (not pd.isna(bHValue)) and (
  235. bHValue > 75 and bHValue < 95):
  236. res = ''
  237. else:
  238. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  239. elif soilType == '典型棕壤' or soilType == '白浆化棕壤' or soilType == '潮棕壤' or soilType == '棕壤性土' or soilType == '棕壤性土':
  240. if (not pd.isna(cationChange)) and (cationChange > 5 and cationChange < 20) and (not pd.isna(bHValue)) and (
  241. cationChange > 25 and cationChange < 65):
  242. res = ''
  243. else:
  244. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  245. elif soilType == '典型山地草甸土' or soilType == '山地草原草甸土' or soilType == '山地灌丛草甸土':
  246. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 20) and (not pd.isna(bHValue)) and (
  247. bHValue > 15 and bHValue < 30):
  248. res = ''
  249. else:
  250. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  251. elif soilType == '酸性紫色土' or soilType == '中性紫色土' or soilType == '石灰性紫色土':
  252. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 20) and (not pd.isna(bHValue)) and (
  253. bHValue > 50 and bHValue < 70):
  254. res = ''
  255. else:
  256. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  257. elif soilType == '红色石灰土' or soilType == '黑色石灰土' or soilType == '棕色石灰土' or soilType == '黄色石灰土' :
  258. if (not pd.isna(cationChange)) and (cationChange > 15 and cationChange < 30) and (not pd.isna(bHValue)) and (
  259. bHValue > 70 and bHValue < 100):
  260. res = ''
  261. else:
  262. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  263. elif soilType == '酸性石质土' or soilType == '中性石质土' or soilType == '钙质石质土' or soilType == '含盐石质土':
  264. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 15) and (not pd.isna(bHValue)) and (
  265. bHValue > 45 and bHValue < 65):
  266. res = ''
  267. else:
  268. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  269. elif soilType == '酸性粗骨土' or soilType == '中性粗骨土' or soilType == '钙质粗骨土' or soilType == '硅质盐粗骨土':
  270. if (not pd.isna(cationChange)) and (cationChange > 5 and cationChange < 15) and (not pd.isna(bHValue)) and (
  271. bHValue > 20 and bHValue < 50):
  272. res = ''
  273. else:
  274. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  275. elif soilType == '典型潮土' or soilType == '灰潮土' or soilType == '脱潮土' or soilType == '湿潮土' or soilType == '盐化潮土' or soilType == '碱化潮土' or soilType == '灌於潮土':
  276. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 30) and (not pd.isna(bHValue)) and (
  277. bHValue > 70 and bHValue < 100):
  278. res = ''
  279. else:
  280. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  281. elif soilType == '典型砂姜黑土' or soilType == '石灰性砂姜黑土' or soilType == '盐化砂姜黑土' or soilType == '碱化砂姜黑土' or soilType == '黑粘土':
  282. if (not pd.isna(cationChange)) and (cationChange > 18 and cationChange < 35) and (not pd.isna(bHValue)) and (
  283. bHValue > 90 and bHValue < 100):
  284. res = ''
  285. else:
  286. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  287. elif soilType == '淹育水稻土':
  288. if (not pd.isna(cationChange)) and (cationChange > 20 and cationChange < 30) and (not pd.isna(bHValue)) and (
  289. bHValue > 85 and bHValue < 90):
  290. res = ''
  291. else:
  292. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  293. elif soilType == '潴育水稻土':
  294. if (not pd.isna(cationChange)) and (cationChange > 12 and cationChange < 20) and (not pd.isna(bHValue)) and (
  295. bHValue > 60 and bHValue < 80):
  296. res = ''
  297. else:
  298. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  299. elif soilType == '潜育水稻土':
  300. if (not pd.isna(cationChange)) and (cationChange > 15 and cationChange < 25) and (not pd.isna(bHValue)) and (
  301. bHValue > 75 and bHValue < 90):
  302. res = ''
  303. else:
  304. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  305. elif soilType == '漂洗水稻土':
  306. if (not pd.isna(cationChange)) and (cationChange > 10 and cationChange < 20) and (not pd.isna(bHValue)) and (
  307. bHValue > 65 and bHValue < 80):
  308. res = ''
  309. else:
  310. res = '存疑:该土壤类型的阳离子交换量或盐基饱和度范围存疑。'
  311. return res
  312. def cation_value(arr):
  313. phList = [] # 保存ph存疑数据
  314. cationList = [] # 保存阳离子存疑数据
  315. exchangeableSalt = [] # 保存交换性盐基总量存疑数据
  316. exchangeableCa = [] # 保存交换性钙总量存疑数据
  317. exchangeableMg = [] # 保存交换性镁总量存疑数据
  318. exchangeableK = [] # 保存交换性钾总量存疑数据
  319. exchangeableNa = [] # 保存交换性钠总量存疑数据
  320. summaryList = [] # 保存ph 离子和 盐基饱和度范围存疑数据
  321. soilTypeList = [] # 保存土壤类型 阳离子交换量cmol(+)/kg 和盐基饱和度范围存疑数据
  322. waterMount = [] # 保存含水量存疑数据 含水量应小于10%
  323. phTar = [] # 保存ph异常指标
  324. cationTar = [] # 保存阳离子异常指标
  325. exchangeableSaltTar = [] # 保存交换性盐基总量异常指标
  326. exchangeableCaTar = [] # 保存交换性钙异常指标
  327. exchangeableMgTar = [] # 保存交换性镁异常指标
  328. exchangeableKTar = [] # 保存交换性钾异常指标
  329. exchangeableNaTar = [] # 保存交换性钠异常指标
  330. summaryListTar = [] # 保存ph 离子和 盐基饱和度异常指标
  331. soilTypeListTar = [] # 保存土壤类型 阳离子交换量cmol(+)/kg 和盐基饱和度异常数据
  332. waterMountTar = [] # 保存含水量异常指标
  333. try:
  334. for index, row in arr.iterrows():
  335. # 风干样含水量 0.5-5,存疑
  336. if pd.isna(row['含水量']) or row['含水量'] > 5 or row['含水量'] < 0.5:
  337. waterMount.append('风干试样含水量(分析基):复核数据合理性。')
  338. waterMountTar.append('风干试样含水量(分析基)。')
  339. else:
  340. waterMount.append('')
  341. waterMountTar.append('')
  342. # (1)pH在[4, 9]范围之外的,存疑;
  343. if pd.isna(row['pH']) or row['pH'] < 4 or row['pH'] > 9:
  344. phList.append('pH:复核数据合理性。')
  345. phTar.append('pH。')
  346. else:
  347. phList.append('')
  348. phTar.append('')
  349. # (2)阳离子交换量在[6, 38]范围之外的,存疑;
  350. if row['阳离子交换量Cmol(+)/kg'] < 6 or row['阳离子交换量Cmol(+)/kg'] > 38:
  351. cationList.append('阳离子交换量:复核数据合理性。')
  352. cationTar.append('阳离子交换量。')
  353. else:
  354. cationList.append('')
  355. cationTar.append('')
  356. # (3)交换性盐基总量在[3, 30]范围之外的,存疑;
  357. if row['交换性盐总量Cmol(+)/kg'] <3 or row['交换性盐总量Cmol(+)/kg'] > 30:
  358. exchangeableSalt.append('交换性盐基总量:复核数据合理性。')
  359. exchangeableSaltTar.append('交换性盐总量。')
  360. else:
  361. exchangeableSalt.append('')
  362. exchangeableSaltTar.append('')
  363. # (4)交换性钙在[1, 25]范围之外的,存疑;
  364. if row['交换性钙Cmol(1/2Ca2+)/kg'] < 1 or row['交换性钙Cmol(1/2Ca2+)/kg'] > 25:
  365. exchangeableCa.append('交换性钙:交换性钙复核数据合理性。')
  366. exchangeableCaTar.append('交换性钙。')
  367. else:
  368. exchangeableCa.append('')
  369. exchangeableCaTar.append('')
  370. # (5)交换性镁在[0.5, 12.5]范围之外的,存疑;
  371. if row['交换性镁cmol(1/2Mg2+)/kg'] < 0.5 or row['交换性镁cmol(1/2Mg2+)/kg'] > 12.8:
  372. exchangeableMg.append('交换性镁:复核数据合理性。')
  373. exchangeableMgTar.append('交换性镁。')
  374. else:
  375. exchangeableMg.append('')
  376. exchangeableMgTar.append('')
  377. # (6)交换性钾在[0.1, 1.5]范围之外的,存疑;
  378. if row['交换性钾Cmol(+)/kg'] < 0.1 or row['交换性钾Cmol(+)/kg'] > 1.5:
  379. exchangeableK.append('交换性钾:复核数据合理性。')
  380. exchangeableKTar.append('交换性钾。')
  381. else:
  382. exchangeableK.append('')
  383. exchangeableKTar.append('')
  384. # (7)交换性钠在[0.1, 2]范围之外的,存疑;
  385. if row['交换性钠cmol(+)/kg'] < 0.1 or row['交换性钠cmol(+)/kg'] > 2:
  386. if row['交换性钠cmol(+)/kg'] > 2:
  387. exchangeableNa.append('交换性钠:复核数据合理性,关联pH审核。')
  388. exchangeableNaTar.append('交换性钠。')
  389. else:
  390. exchangeableNa.append('交换性钠:复核数据合理性。')
  391. exchangeableNaTar.append('交换性钠。')
  392. else:
  393. exchangeableNa.append('')
  394. exchangeableNaTar.append('')
  395. # (8)pH<7.5,阳离子交换量>交换性盐总量>四大离子之和,且盐基饱和度小于100 %;违反则存疑;pH≥7.5,交换性盐总量 = 四大离子之和,盐基饱和度范围在80~120 %;违反则存疑;
  396. if ((not pd.isna(row['pH']) and row['pH']<7.5 and (row['阳离子交换量Cmol(+)/kg']>row['交换性盐总量Cmol(+)/kg']) and (row['交换性盐总量Cmol(+)/kg']>row['四大离子之和']) and row['盐基饱和度%']*100 <100 ) or
  397. ((not pd.isna(row['pH']) and row['pH']>=7.5 and row['交换性盐总量Cmol(+)/kg']==row['四大离子之和'] and (row['盐基饱和度%']*100 <120 and row['盐基饱和度%']*100 >80 )))or
  398. ((not pd.isna(row['pH']) and row['pH']<6 and row['盐基饱和度%'] >80))
  399. ):
  400. summaryList.append('')
  401. summaryListTar.append('')
  402. else:
  403. summaryList.append('存疑:ph值、阳离子交换量、交换性盐总量、离子总和、盐基饱和度之间关系存疑。')
  404. summaryListTar.append('盐基饱和度。')
  405. soilRes = soilTypeValue(row)
  406. soilTypeList.append(soilRes)
  407. # print('pd.Series(phList)',pd.Series(phList) + pd.Series(cationList)+pd.Series(exchangeableSalt))
  408. # print('pd.Series(cationList)', pd.Series(exchangeableSalt))
  409. # print('res---', pd.Series(phList)+pd.Series(cationList)+pd.Series(exchangeableSalt)+pd.Series(exchangeableCa)+pd.Series(exchangeableMg)+pd.Series(exchangeableK)+pd.Series(exchangeableNa)+pd.Series(summaryList))
  410. checkData = pd.DataFrame({
  411. '审核结果': pd.Series(phList)+pd.Series(cationList)+pd.Series(exchangeableSalt)+pd.Series(exchangeableCa)+pd.Series(exchangeableMg)+pd.Series(exchangeableK)+pd.Series(exchangeableNa)+pd.Series(summaryList)+pd.Series(soilTypeList)+pd.Series(waterMount),
  412. '异常指标': pd.Series(phTar)+pd.Series(cationTar)+pd.Series(exchangeableSaltTar)+pd.Series(exchangeableCaTar)+pd.Series(exchangeableMgTar)+pd.Series(exchangeableKTar)+pd.Series(exchangeableNaTar)+pd.Series(summaryListTar)+pd.Series(waterMountTar)
  413. })
  414. return checkData
  415. except Exception as err:
  416. print('阳离子量判断出错!请检查cation_value中判断阳离子量内容', err)
  417. # 表8 8大离子基础数据判断
  418. def eight_ion_coun(arr, summary):
  419. try:
  420. allArr = [] # 存储水溶性盐总量存疑数据
  421. conductivity = [] # 存储电导率存疑数据
  422. naArr = [] # 存储钠离子存疑数据
  423. kArr = [] # 存储钾离子存疑数据
  424. caArr = [] # 存储钙离子存疑数据
  425. mgArr = [] # 存储镁离子存疑数据
  426. coArr = [] # 存储碳酸根离子存疑数据
  427. cohArr = [] # 存储碳酸氢根离子存疑数据
  428. soArr = [] # 存储硫酸根离子存疑数据
  429. clArr = [] # 氯离子存疑数据
  430. totalCom = [] # 全盐量小于八大离子和存疑数据
  431. phCoArr = [] # ph 碳酸根存疑数据
  432. changeComArr = [] #交换性离子高于水溶性离子存疑数据
  433. rateArr = [] # (水溶性全盐量-八大离子加和)/八大离子加和×100 存疑数据
  434. subtractionArr=[] #阳离子-阴离子 不在范围内
  435. # 存放异常指标
  436. allArrTar = [] # 存储水溶性盐总量异常指标
  437. conductivityTar = [] # 存储电导率异常指标
  438. naArrTar = [] # 存储钠离子异常指标
  439. kArrTar = [] # 存储钾离子异常指标
  440. caArrTar = [] # 存储钙离子异常指标
  441. mgArrTar = [] # 存储镁离子异常指标
  442. coArrTar = [] # 存储碳酸根离子异常指标
  443. cohArrTar = [] # 存储碳酸氢根离子异常指标
  444. soArrTar = [] # 存储硫酸根离子异常指标
  445. clArrTar = [] # 氯离子异常指标
  446. totalComTar = [] # 全盐量小于八大离子和异常指标
  447. phCoArrTar = [] # ph 碳酸根异常指标
  448. changeComArrTar = [] # 交换性离子高于水溶性离子异常指标
  449. rateArrTar = [] # (水溶性全盐量-八大离子加和)/八大离子加和×100 异常指标
  450. subtractionArrTar = [] # 阳离子-阴离子 异常指标
  451. #(2)水溶性盐总量在[0.1, 2]范围之外的,存疑;
  452. for index, row in arr.iterrows():
  453. if (not pd.isna(row['水溶性全盐量g/kg']) and row['水溶性全盐量g/kg'] < 0.1) or (not pd.isna(row['水溶性全盐量g/kg']) and row['水溶性全盐量g/kg'] > 2):
  454. allArr.append('全盐量:复核数据合理性。')
  455. allArrTar.append('全盐量。')
  456. else:
  457. allArr.append('')
  458. allArrTar.append('')
  459. #(3)电导率在[0.01, 2]范围之外的,存疑;
  460. if ( not pd.isna(row['电导率ms/cm']) and row['电导率ms/cm'] < 0.01) or (not pd.isna(row['电导率ms/cm']) and row['电导率ms/cm'] > 2):
  461. conductivity.append('电导率:复核数据合理性。')
  462. conductivityTar.append('电导率。')
  463. else:
  464. conductivity.append('')
  465. conductivityTar.append('')
  466. #(4)水溶性钠在[0.05, 0.5]范围之外的,存疑;
  467. if (not pd.isna(row['水溶性钠离子含量Cmol(Na+)/kg']) and row['水溶性钠离子含量Cmol(Na+)/kg'] <0.05) or (pd.isna(row['水溶性钠离子含量Cmol(Na+)/kg']) and row['水溶性钠离子含量Cmol(Na+)/kg'] > 0.5):
  468. naArr.append('水溶性钠离子:水溶性钠离子复核数据合理性。')
  469. naArrTar.append('水溶性钠离子。')
  470. else:
  471. naArr.append('')
  472. naArrTar.append('')
  473. #(5)水溶性钾在[0.01, 0.5]范围之外的,存疑;
  474. if (not pd.isna(row['水溶性钾离子含量Cmol(K+)/kg']) and row['水溶性钾离子含量Cmol(K+)/kg'] <0.01) or ( not pd.isna(row['水溶性钾离子含量Cmol(K+)/kg']) and row['水溶性钾离子含量Cmol(K+)/kg'] > 0.5):
  475. kArr.append('水溶性钾离子:复核数据合理性。')
  476. kArrTar.append('水溶性钾离子。')
  477. else:
  478. kArr.append('')
  479. kArrTar.append('')
  480. #(6)水溶性钙在[0.25, 5]范围之外的,存疑;
  481. if (not pd.isna(row['水溶性钙离子含量cmol(1/2Ca2+)/kg']) and row['水溶性钙离子含量cmol(1/2Ca2+)/kg'] <0.25) or (not pd.isna(row['水溶性钙离子含量cmol(1/2Ca2+)/kg']) and row['水溶性钙离子含量cmol(1/2Ca2+)/kg'] > 0.5):
  482. caArr.append('水溶性钙离子:复核数据合理性。')
  483. caArrTar.append('水溶性钙离子。')
  484. else:
  485. caArr.append('')
  486. caArrTar.append('')
  487. #(7)水溶性镁在[0.125, 2.5]范围之外的,存疑;
  488. if (not pd.isna(row['水溶性镁离子Cmol(1/2Mg2+)/kg']) and row['水溶性镁离子Cmol(1/2Mg2+)/kg'] <0.125) or (not pd.isna(row['水溶性镁离子Cmol(1/2Mg2+)/kg']) and row['水溶性镁离子Cmol(1/2Mg2+)/kg'] > 2.5):
  489. mgArr.append('水溶性镁离子:复核数据合理性。')
  490. mgArrTar.append('水溶性镁离子。')
  491. else:
  492. mgArr.append('')
  493. mgArrTar.append('')
  494. #(8)水溶性碳酸根在[0.01, 2.5]范围之外的,存疑;
  495. if (not pd.isna(row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg']) and row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg'] <0.01) or (not pd.isna(row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg']) and row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg'] > 2.5):
  496. coArr.append('水溶性碳酸根:复核数据合理性。')
  497. coArrTar.append('水溶性碳酸根。')
  498. else:
  499. coArr.append('')
  500. coArrTar.append('')
  501. #(9)水溶性碳酸氢根在[0.05, 5]范围之外的,存疑;
  502. if (not pd.isna(row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg']) and row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg'] <0.05) or (not pd.isna(row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg']) and row['水溶性碳酸氢离子含量cmol(1/2HCO3-)/kg'] > 5):
  503. cohArr.append('水溶性碳酸氢根:复核数据合理性。')
  504. cohArrTar.append('水溶性碳酸氢根。')
  505. else:
  506. cohArr.append('')
  507. cohArrTar.append('')
  508. #(10)水溶性硫酸根在[0.25, 2.5]范围之外的,存疑;
  509. if (not pd.isna(row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg']) and row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg'] <0.25) or (not pd.isna(row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg']) and row['水溶性硫酸根离子含量cmol(1/2SO42-)/kg'] > 2.5):
  510. soArr.append('水溶性硫酸根:复核数据合理性。')
  511. soArrTar.append('水溶性硫酸根。')
  512. else:
  513. soArr.append('')
  514. soArrTar.append('')
  515. #(11)水溶性氯根在[0.5, 5]范围之外的,存疑;
  516. if (not pd.isna(row['水溶性氯离子含量cmol(Cl-)/kg']) and row['水溶性氯离子含量cmol(Cl-)/kg'] <0.5) or (not pd.isna(row['水溶性氯离子含量cmol(Cl-)/kg']) and row['水溶性氯离子含量cmol(Cl-)/kg'] > 5):
  517. clArr.append('水溶性氯根:复核数据合理性。')
  518. clArrTar.append('水溶性氯根。')
  519. else:
  520. clArr.append('')
  521. clArrTar.append('')
  522. #(12)水溶性盐总量大于等于八大离子之和,违背则存疑;土地利用类型为菜地的,可能不符合这个规律;
  523. if (not pd.isna( row['水溶性全盐量g/kg']) and not pd.isna(row['八大离子加和g/kg']) and row['水溶性全盐量g/kg'] < row['八大离子加和g/kg']):
  524. totalCom.append('存疑:水溶性全盐量小于八大离子之和。')
  525. totalComTar.append('水溶性全盐量。')
  526. else:
  527. totalCom.append('')
  528. totalComTar.append('')
  529. #(13)水溶性八大离子换算为g / kg,如水溶性钠离子g / kg = 水溶性钠离子cmol(Na +) / kg×23g / mol×10 - 2; 这里在计算离子和时已转换
  530. #(14)pH<8,碳酸根基本为0
  531. if row['pH'] <8 and not pd.isna(row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg']) and row['水溶性碳酸根离子含量cmol(1/2CO32+)/kg'] != 0:
  532. phCoArr.append('水溶性碳酸根:pH<8水溶性碳酸根不为0。')
  533. phCoArrTar.append('水溶性碳酸根。')
  534. else:
  535. phCoArr.append('')
  536. phCoArrTar.append('')
  537. #(15)交换性四大盐离子均要高于水溶性四大盐离子(钙镁钾钠)
  538. naBool = not pd.isna(row['水溶性钠离子含量Cmol(Na+)/kg'])
  539. kBool = not pd.isna(row['水溶性钾离子含量Cmol(K+)/kg'])
  540. caBool = not pd.isna(row['水溶性钙离子含量cmol(1/2Ca2+)/kg'])
  541. mgBool = not pd.isna(row['水溶性镁离子Cmol(1/2Mg2+)/kg'])
  542. sumNa = not pd.isna(summary.loc[index,'交换性钠'])
  543. sumK = not pd.isna(summary.loc[index, '交换性钾'])
  544. sumCa = not pd.isna(summary.loc[index, '交换性钙'])
  545. sumMg = not pd.isna(summary.loc[index, '交换性镁'])
  546. if (naBool and sumNa and row['水溶性钠离子含量Cmol(Na+)/kg']>summary.loc[index,'交换性钠']) or (
  547. kBool and sumK and row['水溶性钾离子含量Cmol(K+)/kg']>summary.loc[index,'交换性钾']) or (
  548. caBool and sumCa and row['水溶性钙离子含量cmol(1/2Ca2+)/kg']>summary.loc[index,'交换性钙']) or (
  549. mgBool and sumMg and row['水溶性镁离子Cmol(1/2Mg2+)/kg']>summary.loc[index,'交换性镁']):
  550. changeComArr.append('存疑:交换性盐基总量低于于水溶性盐离子。')
  551. else:
  552. changeComArr.append('')
  553. #(16)(水溶性全盐量 - 八大离子加和) / 八大离子加和 * 100,不超过±20 %
  554. if not pd.isna(row['(水溶性全盐量-八大离子加和)/水溶性全盐量×100']) and (row['(水溶性全盐量-八大离子加和)/水溶性全盐量×100'] < -0.2 or row['(水溶性全盐量-八大离子加和)/水溶性全盐量×100'] > 0.2) :
  555. rateArr.append('存疑:(水溶性全盐量-八大离子加和)/水溶性全盐量×100复核数据合理性。')
  556. else:
  557. rateArr.append('')
  558. #(17)阳离子总量 - 阴离子总量应基本相等,超过±1则提示异常
  559. if not pd.isna(row['阳离子总量-阴离子总量']) and (row['阳离子总量-阴离子总量'] < -1 or row['阳离子总量-阴离子总量'] > 1) :
  560. subtractionArr.append('存疑:阳离子总量 - 阴离子总量复核数据合理性。')
  561. else:
  562. subtractionArr.append('')
  563. resData = pd.DataFrame({
  564. '审核结果': pd.Series(allArr) + pd.Series(conductivity) + pd.Series(naArr) +
  565. pd.Series(kArr) + pd.Series(caArr) + pd.Series(mgArr) + pd.Series(coArr) + pd.Series(
  566. cohArr) + pd.Series(soArr) + pd.Series(clArr) + pd.Series(totalCom) + pd.Series(
  567. phCoArr) + pd.Series(changeComArr) + pd.Series(rateArr) + pd.Series(subtractionArr),
  568. '异常指标': pd.Series(allArrTar) + pd.Series(conductivityTar) + pd.Series(naArrTar) +
  569. pd.Series(kArrTar) + pd.Series(caArrTar) + pd.Series(mgArrTar) + pd.Series(coArrTar) + pd.Series(
  570. cohArrTar) + pd.Series(soArrTar) + pd.Series(clArrTar) + pd.Series(totalComTar) + pd.Series(
  571. phCoArrTar)
  572. })
  573. return resData
  574. except Exception as err:
  575. print('八大离子判断出错!请检查eight_ion_coun中判断离子内容', err)
  576. # 表10 有机质、全氮、全磷、全钾数据
  577. def nutrient_data(arr):
  578. try:
  579. organicMatter = [] # 有机质存疑数据
  580. NArr = [] # 全氮存疑数据
  581. PArr = [] # 全磷存疑数据
  582. KArr = [] # 全钾存疑数据
  583. availableP = [] # 有效磷存疑数据
  584. availablek = [] #速效钾存疑数据
  585. slowlyK= [] #缓效钾存疑数据
  586. organicRate = [] #有机质 / 全氮比值存疑数据
  587. availablePCom = [] #有效磷<3和大于60,提示异常;
  588. availableTxt = [] # 速效钾<50提示异常
  589. availablekCom = [] # 速效钾>缓效钾 存疑数据
  590. sKErr = [] # 保存交换性钾不等于速效钾
  591. # 异常指标
  592. organicMatterTar = [] # 有机质异常指标
  593. NArrTar = [] # 全氮异常指标
  594. PArrTar = [] # 全磷异常指标
  595. KArrTar = [] # 全钾异常指标
  596. availablePTar = [] # 有效磷异常指标
  597. availablekTar = [] # 速效钾异常指标
  598. slowlyKTar = [] # 缓效钾异常指标
  599. sKErrTar = [] # 保存交换性钾不等于速效钾
  600. for index, row in arr.iterrows():
  601. # 交换性钾 == 速效钾
  602. if not pd.isna(row['速效钾mg/kg']) and not pd.isna(row['交换性钾']) and ((row['速效钾mg/kg'] - row['交换性钾']*391)/ (row['交换性钾']*391) > 0.2 or (row['速效钾mg/kg'] - row['交换性钾']*391)/ (row['交换性钾']*391) < -0.2):
  603. sKErr.append('存疑:交换性钾和速效钾误差超20%。')
  604. sKErrTar.append('交换性钾、速效钾。')
  605. else:
  606. sKErr.append('')
  607. sKErrTar.append('')
  608. #(2)有机质在[2, 50]范围之外的,存疑;有机质<5提示异常;
  609. if row['有机质g/kg'] < 2 or row['有机质g/kg'] >50:
  610. organicMatter.append('有机质:复核数据合理性。')
  611. organicMatterTar.append('有机质。')
  612. else:
  613. organicMatter.append('')
  614. organicMatterTar.append('')
  615. #(3)全氮在[0.1, 2.5]范围之外的;存疑;
  616. if row['全氮g/kg'] < 0.1 or row['全氮g/kg'] > 2.5:
  617. NArr.append('全氮:复核数据合理性。')
  618. NArrTar.append('全氮。')
  619. else:
  620. NArr.append('')
  621. NArrTar.append('')
  622. #(4)全磷在[0.18, 1.5]范围之外的;存疑;
  623. if row['全磷g/kg'] < 0.18 or row['全磷g/kg'] > 1.5:
  624. PArr.append('全磷:复核数据合理性。')
  625. PArrTar.append('全磷。')
  626. else:
  627. PArr.append('')
  628. PArrTar.append('')
  629. #(5)全钾在[10, 29]范围之外的;存疑;
  630. if row['全钾g/kg'] < 10 or row['全钾g/kg'] > 29:
  631. KArr.append('全钾:复核数据合理性。')
  632. KArrTar.append('全钾。')
  633. else:
  634. KArr.append('')
  635. KArrTar.append('')
  636. #(6)有效磷在[1, 80]范围之外的;存疑; 耕地 超过80存疑
  637. if (row['pH'] >= 6.5 and (row['有效磷g/kg'] < 3 or row['有效磷g/kg'] > 60)) or (row['pH'] < 6.5 and (row['有效磷g/kg'] <1 or row['有效磷g/kg'] > 80) or (row['编号'][6:10] == '0101' or row['编号'][6:10] == '0102' or row['编号'][6:10] == '0103') and row['有效磷g/kg'] > 60) :
  638. availableP.append('有效磷:复核数据合理性。')
  639. availablePTar.append('有效磷。')
  640. else:
  641. availableP.append('')
  642. availablePTar.append('')
  643. # if row['有效磷g/kg'] < 1 or row['有效磷g/kg'] > 60 or ((row['编号'][6:11] == '0101' or row['编号'][6:11] == '0102' or row['编号'][6:11] == '0103') and row['有效磷g/kg'] > 60):
  644. # availableP.append('存疑:有效磷复核数据合理性。')
  645. # else:
  646. # availableP.append('')
  647. #(7)速效钾在[30, 300] 范围之外的;存疑; 耕地超过300存疑
  648. if row['速效钾mg/kg'] < 30 or row['速效钾mg/kg'] > 300 or ((row['编号'][6:10] == '0101' or row['编号'][6:10] == '0102' or row['编号'][6:10] == '0103') and row['速效钾mg/kg'] > 300):
  649. availablek.append('速效钾:复核数据合理性。')
  650. availablekTar.append('速效钾。')
  651. else:
  652. availablek.append('')
  653. availablekTar.append('')
  654. #(8)缓效钾在[100, 2000]范围之外的;存疑;
  655. if row['缓效钾mg/kg'] < 100 or row['缓效钾mg/kg'] > 2000:
  656. slowlyK.append('缓效钾:复核数据合理性。')
  657. slowlyKTar.append('缓效钾。')
  658. else:
  659. slowlyK.append('')
  660. slowlyKTar.append('')
  661. #(9)有机质 / 全氮比值≥20和≤13,提示存疑
  662. if row['有机质g/kg']/row['全氮g/kg'] >=20 or row['有机质g/kg']/row['全氮g/kg'] <=13 :
  663. organicRate.append('存疑:有机质/全氮比值复核数据合理性。')
  664. else:
  665. organicRate.append('')
  666. #(10)有机质、全氮含量异常高,但速效养分特低,提示异常 无法量化不处理
  667. #(11)母岩为片麻岩,但全钾、速效缓效钾含量低,提示异常 无法量化不处理
  668. #(12)有效磷<3和大于60,提示异常;速效钾<50提示异常
  669. if row['有效磷g/kg'] < 3 or row['有效磷g/kg'] > 60:
  670. availablePCom.append('有效磷:复核数据合理性。')
  671. else:
  672. availablePCom.append('')
  673. if row['速效钾mg/kg'] < 50:
  674. availableTxt.append('速效钾:复核数据合理性。')
  675. else:
  676. availableTxt.append('')
  677. #(13)速效钾>缓效钾,提示异常
  678. if row['速效钾mg/kg'] > row['缓效钾mg/kg']:
  679. availablekCom.append('异常:速效钾大于缓效钾。')
  680. else:
  681. availablekCom.append('')
  682. resData = pd.DataFrame({
  683. '审核结果': pd.Series(organicMatter) + pd.Series(NArr) + pd.Series(PArr) +
  684. pd.Series(KArr) + pd.Series(availableP) + pd.Series(availablek) + pd.Series(slowlyK) + pd.Series(
  685. organicRate) + pd.Series(availablePCom) + pd.Series(availablekCom) + pd.Series(availableTxt) + pd.Series(availablePCom) + pd.Series(sKErr),
  686. '异常指标': pd.Series(organicMatterTar) + pd.Series(NArrTar) + pd.Series(PArrTar) +
  687. pd.Series(KArrTar) + pd.Series(availablePTar) + pd.Series(availablekTar) + pd.Series(slowlyKTar) + pd.Series(sKErrTar)
  688. })
  689. return resData
  690. except Exception as err:
  691. print('有机质、全氮、全磷、全钾数据判断出错!请检查nutrient_data中判断内容', err)
  692. # 表12 土壤指标判断规则
  693. def soil_metal(arr):
  694. try:
  695. effectiveL = [] # 有效硫存疑数据
  696. effectiveG = [] # 有效硅存疑数据
  697. effectiveT = [] # 有效铁存疑数据
  698. effectiveM = [] # 有效锰存疑数据
  699. effectiveCu = [] # 有效铜存疑数据
  700. effectiveX = [] # 有效锌存疑数据
  701. effectiveP = [] # 有效硼存疑数据
  702. effectiveMu = [] # 有效钼存疑数据
  703. # 存疑指标
  704. effectiveLTar = [] # 有效硫
  705. effectiveGTar = [] # 有效硅
  706. effectiveTTar = [] # 有效铁
  707. effectiveMTar = [] # 有效锰
  708. effectiveCuTar = [] # 有效铜
  709. effectiveXTar = [] # 有效锌
  710. effectivePTar = [] # 有效硼
  711. effectiveMutar = [] # 有效钼
  712. for index, row in arr.iterrows():
  713. #(1)有效硫在[2, 60]范围之外的,存疑;
  714. if (not pd.isna(row['有效硫mg/kg']) and row['有效硫mg/kg'] <2) or (not pd.isna(row['有效硫mg/kg']) and row['有效硫mg/kg'] >60):
  715. effectiveL.append('有效硫:复核数据合理性。')
  716. effectiveLTar.append('有效硫。')
  717. else:
  718. effectiveL.append('')
  719. effectiveLTar.append('')
  720. #(2)有效硅在[10, 500]范围之外的,存疑;
  721. if ( not pd.isna(row['有效硅mg/kg']) and row['有效硅mg/kg'] <10) or (not pd.isna(row['有效硅mg/kg']) and row['有效硅mg/kg'] >500):
  722. effectiveG.append('有效硅:复核数据合理性。')
  723. effectiveGTar.append('有效硅。')
  724. else:
  725. effectiveG.append('')
  726. effectiveGTar.append('')
  727. #(3)有效铁在[5, 300]范围之外的,存疑;
  728. if ( not pd.isna(row['有效铁mg/kg']) and row['有效铁mg/kg'] <5) or (not pd.isna(row['有效铁mg/kg']) and row['有效铁mg/kg'] >300):
  729. effectiveT.append('有效铁:复核数据合理性。')
  730. effectiveTTar.append('有效铁。')
  731. else:
  732. effectiveT.append('')
  733. effectiveTTar.append('')
  734. #(4)有效锰在[5, 200]范围之外的,存疑;
  735. if (not pd.isna(row['有效锰mg/kg']) and row['有效锰mg/kg'] <5) or (not pd.isna(row['有效锰mg/kg']) and row['有效锰mg/kg'] >200) :
  736. effectiveM.append('有效锰:复核数据合理性。')
  737. effectiveMTar.append('有效锰。')
  738. else:
  739. effectiveM.append('')
  740. effectiveMTar.append('')
  741. #(5)有效铜在[0.1, 8]范围之外的,存疑;
  742. if ( not pd.isna(row['有效铜mg/kg']) and row['有效铜mg/kg'] <0.1) or (not pd.isna(row['有效铜mg/kg']) and row['有效铜mg/kg'] >8):
  743. effectiveCu.append('有效铜:复核数据合理性。')
  744. effectiveCuTar.append('有效铜。')
  745. else:
  746. effectiveCu.append('')
  747. effectiveCuTar.append('')
  748. #(6)有效锌在[0.1, 10] 范围之外的,存疑;
  749. if (not pd.isna(row['有效锌mg/kg']) and row['有效锌mg/kg'] <0.1) or (not pd.isna(row['有效锌mg/kg']) and row['有效锌mg/kg'] >10):
  750. effectiveX.append('有效锌:复核数据合理性。')
  751. effectiveXTar.append('有效锌。')
  752. else:
  753. effectiveX.append('')
  754. effectiveXTar.append('')
  755. #(7)有效硼在[0.1, 2] 范围之外的,存疑;
  756. if (not pd.isna(row['有效硼mg/kg']) and row['有效硼mg/kg'] <0.1) or (not pd.isna(row['有效硼mg/kg']) and row['有效硼mg/kg'] >2):
  757. effectiveP.append('有效硼:复核数据合理性。')
  758. effectivePTar.append('有效硼。')
  759. else:
  760. effectiveP.append('')
  761. effectivePTar.append('')
  762. #(8)有效钼在[0.03, 1]范围之外的,存疑。
  763. if (not pd.isna(row['有效钼mg/kg']) and row['有效钼mg/kg'] <0.03) or (not pd.isna(row['有效钼mg/kg']) and row['有效钼mg/kg'] >1):
  764. effectiveMu.append('有效钼:复核数据合理性。')
  765. effectiveMutar.append('有效钼。')
  766. else:
  767. effectiveMu.append('')
  768. effectiveMutar.append('')
  769. resData = pd.DataFrame({
  770. '审核结果': pd.Series(effectiveL) + pd.Series(effectiveT) + pd.Series(effectiveG) +
  771. pd.Series(effectiveM) + pd.Series(effectiveCu) + pd.Series(effectiveX) + pd.Series(effectiveP) + pd.Series(
  772. effectiveMu),
  773. '异常指标': pd.Series(effectiveLTar) + pd.Series(effectiveTTar) + pd.Series(effectiveGTar) +
  774. pd.Series(effectiveMTar) + pd.Series(effectiveCuTar) + pd.Series(effectiveXTar) + pd.Series(effectivePTar) + pd.Series(
  775. effectiveMutar)
  776. })
  777. return resData
  778. except Exception as err:
  779. print('土壤指标数据判断出错!请检查soil_metal中判断内容', err)
  780. # 表14 土壤重金属判断
  781. # 这里风险值和管控值判断 单独写两个函数
  782. # 风险值
  783. def risk_value(arr):
  784. unnormalValue = []
  785. for index, row in arr.iterrows():
  786. str = ''
  787. if row['编号'][6:10] == '0101': # 水田
  788. # 镉
  789. if (row['pH'] <= 5.5 and row['镉mg/kg'] > 0.3) or (
  790. row['pH'] > 5.5 and row['pH']<= 6.5 and row['镉mg/kg'] > 0.4) or (
  791. row['pH'] >6.5 and row['pH'] <=7.5 and row['镉mg/kg'] > 0.6) or (
  792. row['pH'] > 7.5 and row['镉mg/kg'] > 0.8):
  793. str += '镉超污染风险值筛选值。'
  794. # 汞
  795. if (row['pH'] <= 5.5 and row['汞mg/kg'] > 0.5) or (
  796. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['汞mg/kg'] > 0.5) or (
  797. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['汞mg/kg'] > 0.6) or (
  798. row['pH'] > 7.5 and row['汞mg/kg'] > 1):
  799. str += '汞超污染风险值筛选值。'
  800. # 砷
  801. if (row['pH'] <= 5.5 and row['砷mg/kg'] >30) or (
  802. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['砷mg/kg'] > 30) or (
  803. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['砷mg/kg'] > 25) or (
  804. row['pH'] > 7.5 and row['砷mg/kg'] > 20):
  805. str += '砷超污染风险值筛选值。'
  806. # 铅
  807. if (row['pH'] <= 5.5 and row['铅mg/kg'] > 80) or (
  808. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铅mg/kg'] > 100) or (
  809. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铅mg/kg'] > 140) or (
  810. row['pH'] > 7.5 and row['铅mg/kg'] > 240):
  811. str += '铅超污染风险值筛选值。'
  812. # 铬
  813. if (row['pH'] <= 5.5 and row['铬mg/kg'] > 250) or (
  814. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铬mg/kg'] > 250) or (
  815. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铬mg/kg'] > 300) or (
  816. row['pH'] > 7.5 and row['铬mg/kg'] >350):
  817. str += '铬超污染风险值筛选值。'
  818. else:
  819. # 镉
  820. if (row['pH'] <= 5.5 and row['镉mg/kg'] > 0.3) or (
  821. row['pH'] > 5.5 and row['pH']<= 6.5 and row['镉mg/kg'] > 0.3) or (
  822. row['pH'] >6.5 and row['pH'] <=7.5 and row['镉mg/kg'] > 0.3) or (
  823. row['pH'] > 7.5 and row['镉mg/kg'] > 0.6):
  824. str += '镉超污染风险值筛选值。'
  825. # 汞
  826. if (row['pH'] <= 5.5 and row['汞mg/kg'] > 1.3) or (
  827. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['汞mg/kg'] > 1.8) or (
  828. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['汞mg/kg'] > 2.4) or (
  829. row['pH'] > 7.5 and row['汞mg/kg'] > 3.4):
  830. str += '汞超污染风险值筛选值。'
  831. # 砷
  832. if (row['pH'] <= 5.5 and row['砷mg/kg'] > 40) or (
  833. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['砷mg/kg'] > 40) or (
  834. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['砷mg/kg'] > 30) or (
  835. row['pH'] > 7.5 and row['砷mg/kg'] > 25):
  836. str += '砷超污染风险值筛选值。'
  837. # 铅
  838. if (row['pH'] <= 5.5 and row['铅mg/kg'] > 70) or (
  839. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铅mg/kg'] > 90) or (
  840. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铅mg/kg'] > 120) or (
  841. row['pH'] > 7.5 and row['铅mg/kg'] > 170):
  842. str += '铅超污染风险值筛选值。'
  843. # 铬
  844. if (row['pH'] <= 5.5 and row['铬mg/kg'] > 150) or (
  845. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铬mg/kg'] > 150) or (
  846. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铬mg/kg'] > 200) or (
  847. row['pH'] > 7.5 and row['铬mg/kg'] > 250):
  848. str += '铬超污染风险值筛选值。'
  849. if (row['pH'] <= 5.5 and row['镍mg/kg'] > 60) or (
  850. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['镍mg/kg'] > 70) or (
  851. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['镍mg/kg'] > 100) or (
  852. row['pH'] > 7.5 and row['镍mg/kg'] > 190):
  853. str += '镍超污染风险值筛选值。'
  854. unnormalValue.append(str)
  855. return unnormalValue
  856. # 管制值
  857. def control_value(arr):
  858. unnormalValue = []
  859. for index, row in arr.iterrows():
  860. str = ''
  861. # 镉
  862. if (row['pH'] <= 5.5 and row['镉mg/kg'] > 1.5) or (
  863. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['镉mg/kg'] > 2) or (
  864. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['镉mg/kg'] > 3) or (
  865. row['pH'] > 7.5 and row['镉mg/kg'] > 4):
  866. str += '镉超污染风险值管制值。'
  867. # 汞
  868. if (row['pH'] <= 5.5 and row['汞mg/kg'] > 2) or (
  869. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['汞mg/kg'] > 2.5) or (
  870. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['汞mg/kg'] > 4) or (
  871. row['pH'] > 7.5 and row['汞mg/kg'] > 6):
  872. str += '汞超污染风险值管制值。'
  873. # 砷
  874. if (row['pH'] <= 5.5 and row['砷mg/kg'] > 200) or (
  875. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['砷mg/kg'] > 150) or (
  876. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['砷mg/kg'] > 120) or (
  877. row['pH'] > 7.5 and row['砷mg/kg'] > 100):
  878. str += '砷超污染风险值管制值。'
  879. # 铅
  880. if (row['pH'] <= 5.5 and row['铅mg/kg'] >400) or (
  881. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铅mg/kg'] > 500) or (
  882. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铅mg/kg'] > 700) or (
  883. row['pH'] > 7.5 and row['铅mg/kg'] > 1000):
  884. str += '铅超污染风险值管制值。'
  885. # 铬
  886. if (row['pH'] <= 5.5 and row['铬mg/kg'] > 800) or (
  887. row['pH'] > 5.5 and row['pH'] <= 6.5 and row['铬mg/kg'] > 850) or (
  888. row['pH'] > 6.5 and row['pH'] <= 7.5 and row['铬mg/kg'] > 1000) or (
  889. row['pH'] > 7.5 and row['铬mg/kg'] > 1300):
  890. str += '铬超污染风险值管制值。'
  891. unnormalValue.append(str)
  892. return unnormalValue
  893. def last_metal(arr):
  894. try:
  895. totalGe = [] # 总镉在范围之外
  896. totalGo = [] # 总汞在范围之外
  897. totalShen = [] # 总砷在范围之外
  898. totalPb = [] # 总铅在范围之外
  899. totalG = [] # 总铬在范围之外
  900. totalN = [] # 总镍在范围之外
  901. # 异常指标
  902. totalGeTar = [] # 总镉
  903. totalGoTar = [] # 总汞
  904. totalShenTar = [] # 总砷
  905. totalPbTar = [] # 总铅
  906. totalGTar = [] # 总铬
  907. totalNTar = [] # 总镍
  908. # (1)超过风险筛选值,提示关注
  909. overValue = risk_value(arr) # 超过风险筛选值
  910. # (2)超过风险管控值,提示重点关注
  911. overLimit = control_value(arr) # 超过风险管控值
  912. for index, row in arr.iterrows():
  913. # (3)总镉在[0.03, 0.3]范围之外的,存疑
  914. if row['镉mg/kg'] < 0.03 or row['镉mg/kg'] > 0.3:
  915. totalGe.append('总镉:复核数据合理性。')
  916. totalGeTar.append('总镉。')
  917. else:
  918. totalGe.append('')
  919. totalGeTar.append('')
  920. # (4)总汞在[0.01, 0.3]范围之外的,存疑
  921. if row['汞mg/kg'] < 0.01 or row['汞mg/kg'] > 0.3:
  922. totalGo.append('总汞:复核数据合理性。')
  923. totalGoTar.append('总汞。')
  924. else:
  925. totalGo.append('')
  926. totalGoTar.append('')
  927. # (5)总砷在[0.5, 30]范围之外的,存疑
  928. if row['砷mg/kg'] < 0.5 or row['砷mg/kg'] > 30:
  929. totalShen.append('总砷:复核数据合理性。')
  930. totalShenTar.append('总砷。')
  931. else:
  932. totalShen.append('')
  933. totalShenTar.append('')
  934. # (6)总铅在[2, 100]范围之外的,存疑
  935. if row['铅mg/kg'] < 2 or row['铅mg/kg'] > 100:
  936. totalPb.append('总铅:复核数据合理性。')
  937. totalPbTar.append('总铅。')
  938. else:
  939. totalPb.append('')
  940. totalPbTar.append('')
  941. # (7)总铬在[0.4, 200]范围之外的,存疑
  942. if row['铬mg/kg'] < 0.4 or row['铬mg/kg'] > 200:
  943. totalG.append('总铬:复核数据合理性。')
  944. totalGTar.append('总铬。')
  945. else:
  946. totalG.append('')
  947. totalGTar.append('')
  948. # (8)总镍在[0.3, 100]范围之外的,存疑
  949. if row['镍mg/kg'] < 0.3 or row['镍mg/kg'] > 100:
  950. totalN.append('总镍:复核数据合理性。')
  951. totalNTar.append('总镍。')
  952. else:
  953. totalN.append('')
  954. totalNTar.append('')
  955. resData = pd.DataFrame({
  956. '审核结果': pd.Series(overValue) + pd.Series(overLimit) + pd.Series(totalGe) +
  957. pd.Series(totalGo) + pd.Series(totalShen) + pd.Series(totalPb) + pd.Series(
  958. totalG) + pd.Series(totalN),
  959. '异常指标': pd.Series(totalGeTar) + pd.Series(totalGoTar) + pd.Series(totalShenTar) + pd.Series(totalPbTar) + pd.Series(
  960. totalGTar) + pd.Series(totalNTar)
  961. })
  962. return resData
  963. except Exception as err:
  964. print('土壤重金属指标数据判断出错!请检查last_metal中判断内容', err)