Primeiro, olhe para os requisitos:
O principal é gerar automaticamente o relatório estatístico do Word à direita de acordo com a tabela da esquerda As possibilidades reais são muito mais complicadas do que as mostradas na figura.
Ok, vamos começar a fazer o código!
1. Leitura de dados
import pandas as pd
df = pd.read_csv("11月份数据.csv", encoding='gbk')
# 当前统计月份
month = 11
df = df.query('月份==@month')
df.head(10)
Dados de visualização:
2. Filtragem de dados anormais
Visualize o número de valores ausentes:
pd.isnull(df).sum()
resultado:
区域 0
月份 0
降雨量(mm) 0
降雨距平(mm) 1
观测站 0
dtype: int64
Apenas um dado de valor ausente pode ser excluído diretamente:
df.dropna(inplace=True)
3. Calcule a variação da
precipitação na estação de observação em relação aos anos anteriores. Calcule o número de vezes que a precipitação é maior do que nos anos anteriores, inalterada em relação aos anos anteriores e inferior aos anos anteriores:
rainfall_high = df.eval('`降雨距平(mm)` > 0').value_counts().get(True, 0)
rainfall_equal = df.eval('`降雨距平(mm)` == 0').value_counts().get(True, 0)
rainfall_low = df.eval('`降雨距平(mm)` < 0').value_counts().get(True, 0)
print(rainfall_high, rainfall_equal, rainfall_low)
13 1 18
Nos resultados acima, rain_high representa o número de vezes que a precipitação é maior que o nível médio dos anos anteriores, rain_equal representa o número de vezes que a precipitação é igual ao nível médio dos anos anteriores, e rain_low representa o número de vezes que a precipitação é inferior ao nível médio dos anos anteriores.
Portanto, o primeiro parágrafo do relatório é gerado de acordo com a situação:
p1 = f"{month}月份"
if rainfall_low == 0 or rainfall_high == 0:
if rainfall_equal != 0:
p1 += f"除{rainfall_equal}个观测站降雨量较往年无变化外,"
if rainfall_high == 0:
p1 += f"各气象观测站降雨量较往年均偏低。"
elif rainfall_low == 0:
p1 += f"各气象观测站降雨量较往年均偏高。"
else:
# 10%以内差异认为是持平
if rainfall_high > rainfall_low*1.1:
p1 += f"大部分气象观测站降雨量较往年偏高。"
elif rainfall_low > rainfall_high*1.1:
p1 += f"大部分气象观测站降雨量较往年偏低。"
else:
p1 += f"各气象观测站降雨量较往年整体持平。"
p1
resultado:
'11月份大部分气象观测站降雨量较往年偏低。'
4. Calcule o valor extremo da precipitação em cada região
e gere o segundo parágrafo do relatório:
p2 = ""
t = df['降雨量(mm)']
p2 += f"各区域降雨量在{t.min()}~{t.max()}mm之间,其中{df.loc[t.argmax(), '区域']}区域的降雨量最大,为{t.max()}mm。"
p2
resultado:
'各区域降雨量在0.0~16.0mm之间,其中51a45区域的降雨量最大,为16.0mm。'
5. Estatísticas por subestação de observação A parte
que me faz doer de cabeça vem do código aqui, e há requisitos mais complicados posteriormente que não serão anunciados.
Para cada estação de observação, conte quais áreas são altas, quais áreas são planas e quais áreas são baixas:
p3s = []
for station, tmp in df.groupby('观测站'):
t = tmp['降雨量(mm)']
p3 = f"各区域降雨量在{t.min()}~{t.max()}mm之间,"
rainfall_high_mask = tmp.eval('`降雨距平(mm)` > 0')
rainfall_equal_mask = tmp.eval('`降雨距平(mm)` == 0')
rainfall_low_mask = tmp.eval('`降雨距平(mm)` < 0')
rainfall_high = rainfall_high_mask.value_counts().get(True, 0)
rainfall_equal = rainfall_equal_mask.value_counts().get(True, 0)
rainfall_low = rainfall_low_mask.value_counts().get(True, 0)
# print(rainfall_high, rainfall_equal, rainfall_low)
if rainfall_low == 0 or rainfall_high == 0:
if rainfall_equal != 0:
p3 += '除'
p3 += '、'.join(tmp.loc[rainfall_equal_mask, '区域']+'区域')
p3 += "降雨量较往年无变化外,"
if rainfall_high == 0:
p3 += f"各区域降雨量均较往年偏低"
elif rainfall_low == 0:
p3 += f"各区域降雨量均较往年偏高"
t = tmp['降雨距平(mm)'].abs()
p3 += f"{t.min()}~{t.max()}mm;"
else:
if rainfall_equal != 0:
p3 += '除'
p3 += '、'.join(tmp.loc[rainfall_equal_mask, '区域']+'区域')
p3 += "降雨量较往年无变化,"
# 10%以内差异认为是持平
if rainfall_high > rainfall_low*1.1:
if rainfall_equal == 0:
p3 += '除'
p3 += '、'.join(tmp.loc[rainfall_low_mask, '区域']+'区域')
p3 += "降雨量较往年偏低"
t = tmp.loc[rainfall_low_mask, '降雨距平(mm)'].abs()
if t.shape[0] > 1:
p3 += f"{t.min()}~{t.max()}mm"
else:
p3 += f"{t.min()}mm"
p3 += "外,"
t = tmp.loc[rainfall_high_mask, '降雨距平(mm)'].abs()
p3 += f"其余各区域降雨量较往年偏高{t.min()}~{t.max()}mm;"
elif rainfall_low > rainfall_high*1.1:
if rainfall_equal == 0:
p3 += '除'
p3 += '、'.join(tmp.loc[rainfall_high_mask, '区域']+'区域')
p3 += "降雨量较往年偏高"
t = tmp.loc[rainfall_high_mask, '降雨距平(mm)'].abs()
if t.shape[0] > 1:
p3 += f"{t.min()}~{t.max()}mm"
else:
p3 += f"{t.min()}mm"
p3 += "外,"
t = tmp.loc[rainfall_low_mask, '降雨距平(mm)'].abs()
p3 += f"其余各区域降雨量较往年偏低{t.min()}~{t.max()}mm;"
else:
if rainfall_equal != 0:
p3 = p3[:-1]+'外,'
p3 += f"各区域降雨量较往年偏高和偏低的数量持平,其中"
p3 += '、'.join(tmp.loc[rainfall_low_mask, '区域']+'区域')
p3 += "降雨量较往年偏低"
t = tmp.loc[rainfall_low_mask, '降雨距平(mm)'].abs()
if t.shape[0] > 1:
p3 += f"{t.min()}~{t.max()}mm,"
else:
p3 += f"{t.min()}mm,"
p3 += '、'.join(tmp.loc[rainfall_high_mask, '区域']+'区域')
p3 += "降雨量较往年偏高"
t = tmp.loc[rainfall_high_mask, '降雨距平(mm)'].abs()
if t.shape[0] > 1:
p3 += f"{t.min()}~{t.max()}mm;"
else:
p3 += f"{t.min()}mm;"
p3s.append([station, p3])
p3s[-1][-1] = p3s[-1][-1][:-1]+"。"
p3s
6. Escreva o texto organizado no
conteúdo do arquivo de modelo do Word docxtemplate.docx no Word:
一、{
{ month }}月各气象观测站降雨量实况
(一)降水
{
{ p1 }}
{
{ p2 }}
{%p for station,p3 in p3s %}
{
{ station }}:{
{ p3 }}
{%p endfor %}
qual é:
Código de renderização Python:
from docxtpl import DocxTemplate
tpl = DocxTemplate("docxtemplate.docx")
context = {
'month': month,
'p1': p1,
'p2': p2,
'p3s': p3s,
}
tpl.render(context)
tpl.save("11月降雨量报告.docx")
Após a execução ser concluída, o relatório de análise estatística do Word é obtido: