I am trying to create a script using arcpy to automate a serie of task in ArcGIS.
What I am trying to do is to interpolate rainfall data from a region and then, using hydrological basinshapefiles, clip the big raster file into small raster files. After that, I would like to get all the means values from the small basin raster files and save them into a CSV file together with 2 strings, which identify the raster name and the hydrological basin.
The problem that I am facing is to save the numpy arrays that have
[raster_name, day_interpolated, MEAN_value]
. One example of the output would be the following:
espacializacao_2_1994_D1.tif hydrological_basin_name 111,81740045547
Is numpy array the best approach to write these outputs in a CSV file? Because I already saw some tutorials using the "CSV module" to write directly to CSV files. However, I already tried it without success.
I am saying this because this code is going to be repeated a lot of times, something like 19.000 times. Because I am using it to interpolate daily rainfall data from a 54 years time series. So, I guess that an array of this size is not a good approach to solve this problem.
My code is the following:
[![import arcpy
import numpy as np
from arcpy import sa
from arcpy.sa import *
from calendar import monthrange
# Set environment settings
arcpy.env.workspace = "C:\\Projetos\\ArcGIS\\Teste9"
arcpy.env.overwriteOutput = True
#get the map document
mxd = arcpy.mapping.MapDocument("CURRENT")
#get the data frame
df = arcpy.mapping.ListDataFrames(mxd,"la*")\[0\]
#Months and years to interpolate
mes = \["2"\] #Months
ano = \["1994"\] #Years
#Days to interpolate based in the month lenght
coluna_interpolada_28 = \["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15", "D16", "D17", "D18", "D19", "D20", "D21", "D22", "D23", "D24", "D25", "D26", "D27", "D28"\]
coluna_interpolada_29 = \["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15", "D16", "D17", "D18", "D19", "D20", "D21", "D22", "D23", "D24", "D25", "D26", "D27", "D28", "D29"\]
coluna_interpolada_30 = \["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15", "D16", "D17", "D18", "D19", "D20", "D21", "D22", "D23", "D24", "D25", "D26", "D27", "D28", "D29", "D30"\]
coluna_interpolada_31 = \["D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "D11", "D12", "D13", "D14", "D15", "D16", "D17", "D18", "D19", "D20", "D21", "D22", "D23", "D24", "D25", "D26", "D27", "D28", "D29", "D30", "D31"\]
#Interpolation extent
arcpy.env.extent = arcpy.env.workspace + "\\Shapefile\\" + "PB.shp"
#Final list
lista_final = np.array(\[\], dtype = object)
#Counter that is going to be used to reshape the arrays
contador = 0
#Loop to go through the time series
#For loop with the years
for i_ano in ano:
#For loop with the months
for i_mes in mes:
#Month Range
quantidade_dias = monthrange(int(i_ano), int(i_mes))
#If clauses to define which columns it is goin to interpolate
if quantidade_dias == (1, 28):
coluna_interpolada = coluna_interpolada_28
elif quantidade_dias == (1, 29):
coluna_interpolada = coluna_interpolada_29
elif quantidade_dias == (1, 30):
coluna_interpolada = coluna_interpolada_30
else:
coluna_interpolada = coluna_interpolada_31
#For loop with the days
for i_dia in coluna_interpolada:
tabela = i_mes + "_" + i_ano #Exemplo "2_1994"
in_Table = arcpy.env.workspace + "\\Dados\\" + tabela + ".csv" #Exemplo "2_1994.csv"
x_coords = "LONG"
y_coords = "LAT"
z_coords = "POINT_Z"
out_Layer = "espacializacao" + "_" + tabela + "_" + i_dia #nome da camada "lyr" que vai ser criada
#NOME DO ARQUIVO QUE VAI SER SALVO. Exemplo "espacializacao_2_1994_D2"
out_Layer_shp = out_Layer + "_shp" #nome da camada "shp" que vai ser criada
out_Layer_tif = out_Layer + "_tif"
tamanho_celula = "0,10" #precisar por as aspas, apesar de ser um número
potencia_idw = "2" #precisa por as aspas, apesar de ser um número
raio_de_busca = RadiusVariable(12, 12) #Critério para fazer a interpolação, raio variando até 12 quilômetros até conseguir englobar 12 pontos
# Set the spatial reference
spRef = arcpy.SpatialReference("WGS 1984")
#Create event layer
arcpy.MakeXYEventLayer_management(in_Table, x_coords, y_coords, out_Layer, spRef, "")
#Exporting event layer as shapefile
arcpy.FeatureToPoint_management(out_Layer, arcpy.env.workspace + "\\" + "Shapefile\\Exportados\\" + out_Layer_shp + ".shp","")
#Layer that is going to be deleted "lyr"
lyr = arcpy.mapping.ListLayers(mxd, "espacializacao",df)
#Deleting the layer
for df in arcpy.mapping.ListDataFrames(mxd):
for lyr in arcpy.mapping.ListLayers(mxd, "", df): #O parâmetro que não foi passado foi o WildCard, não precisa
if lyr.name == out_Layer:
arcpy.mapping.RemoveLayer(df, lyr) #Removendo a camada da paleta lateral
#Some variables to define some parameters to the software
camada_editando = out_Layer_shp
coluna_criada = "Media"
tipo_campo = "FLOAT"
precisao_campo = ""
precisao_decimais = ""
comprimento_campo = 50 #Tamanho qualquer suposto
arcpy.AddField_management(camada_editando, coluna_criada, "LONG", precisao_campo,
precisao_decimais, comprimento_campo, "", "NULLABLE",
"NON_REQUIRED", "")
bacias = \["Abiai", "Camaratuba", "Curimatau", "Gramame", "Guaju", "Jacu", "Mamanguape", "Miriri", "Paraiba", "Piranhas", "Trairi"\]
#Code to interpolate
arcpy.gp.Idw_sa(out_Layer_shp, i_dia, arcpy.env.workspace + "\\Raster\\" + out_Layer_tif + ".tif", tamanho_celula, potencia_idw, "VARIABLE 12 12", "")
#Deleting shapefile
arcpy.Delete_management(out_Layer_shp, "")
#For loop to clip the raster file using the shapefiles
for mascara in bacias:
importar_camada = arcpy.env.workspace + "\\Shapefile\\Bacias\\" + mascara + ".shp" #Importing shapefile to clip
arcpy.MakeFeatureLayer_management(importar_camada, mascara)
#Some variables defining some parameters to using in the clip function
camada_para_recortar = out_Layer_tif + ".tif"
camada_resultante = out_Layer + "_recortada"
nome_do_raster = camada_resultante + "_" + mascara + ".tif"
#Function to clip the raster file
arcpy.Clip_management(camada_para_recortar, "", arcpy.env.workspace + "\\Raster\\Recortes\\" + camada_resultante + "_" + mascara + ".tif", mascara, "-3,402823e+038", "ClippingGeometry", "NO_MAINTAIN_EXTENT")
media = arcpy.GetRasterProperties_management (nome_do_raster, "MEAN", "")
lista_strings = np.array(\[out_Layer, mascara\])
lista_medias = np.array(\[media\])
#Name of the file to save the means values
arquivo_com_as_medias = "medias 01"
lista_numpy_temporaria = np.append(lista_strings, lista_medias)
lista_final = np.concatenate((lista_final, lista_numpy_temporaria))
#Deleting the raster clipped
arcpy.Delete_management(nome_do_raster, "")
#Counter
contador = contador + 1
print(lista_final)
#Reshaping the file
lista_final = lista_final.reshape(contador,3)
print(lista_final)
#Saving the arrays to a CSV file
np.savetxt(arcpy.env.workspace + "\\Dados\\Exportados\\" + arquivo_com_as_medias + ".csv", lista_final, fmt="%10s %10s %10s", delimiter=";", header = "")
#Deleting the original raster
arcpy.Delete_management(out_Layer_tif + ".tif", "")][1]][1]
I added a picture with the CSV file that I get using this code. As we can see in the picture, it only saves the data related to the last day interpolated. It is overwriting the data.
Saving the arrays to a CSV file
np.savetxt(arcpy.env.workspace + "\Dados\Exportados\" + arquivo_com_as_medias + ".csv", lista_final, fmt="%10s %10s %10s", delimiter=";", header = "")