9

私はpythonとnumpyに非常に慣れていないので、用語を誤用していたらごめんなさい。

計算を迅速かつ効率的に行うために、ラスターを 2D numpy 配列に変換しました。

  • 各値について、それ以下のすべての値の合計を生成し、その値を新しい配列に書き込むように、numpy 配列全体の累積合計を取得する必要があります。そのように配列全体を循環する必要があります。

  • また、出力を 1 から 100 の間でスケーリングする必要がありますが、その
    方が簡単に思えます。

例によって明確にする試み:

array([[ 4,  1  ,  3   ,  2] dtype=float32)

出力値(最初の行を手動で実行するだけ)を次のように読みたいと思います:

array([[ 10,  1  ,  6   ,  3], etc.

それを行う方法についてのアイデアはありますか?

前もって感謝します!


興味のある人のためのほぼ完成したスクリプト:

#Generate Cumulative Thresholds
#5/15/14

import os
import sys
import arcpy
import numpy as np

#Enable overwriting output data
arcpy.env.overwriteOutput=True

#Set working directory
os.chdir("E:/NSF Project/Salamander_Data/Continuous_Rasters/Canadian_GCM/2020/A2A/")

#Set geoprocessing variables
inRaster = "zero_eurycea_cirrigera_CA2A2020.tif"
des = arcpy.Describe(inRaster)
sr = des.SpatialReference
ext = des.Extent
ll = arcpy.Point(ext.XMin,ext.YMin)

#Convert GeoTIFF to numpy array
a = arcpy.RasterToNumPyArray(inRaster)

#Flatten for calculations
a.flatten()

#Find unique values, and record their indices to a separate object
a_unq, a_inv = np.unique(a, return_inverse=True)

#Count occurences of array indices
a_cnt = np.bincount(a_inv)

#Cumulatively sum the unique values multiplied by the number of
#occurences, arrange sums as initial array
b = np.cumsum(a_unq * a_cnt)[a_inv]

#Divide all values by 10 (reverses earlier multiplication done to
#facilitate accurate translation of ASCII scientific notation
#values < 1 to array)
b /= 10

#Rescale values between 1 and 100
maxval = np.amax(b)
b /= maxval
b *= 100

#Restore flattened array to shape of initial array
c = b.reshape(a.shape)

#Convert the array back to raster format
outRaster = arcpy.NumPyArrayToRaster(c,ll,des.meanCellWidth,des.meanCellHeight)

#Set output projection to match input
arcpy.DefineProjection_management(outRaster, sr)

#Save the raster as a TIFF
outRaster.save("C:/Users/mkcarte2/Desktop/TestData/outRaster.tif")

sys.exit()
4

4 に答える 4

11

繰り返しを処理する方法に応じて、これは機能します。

In [40]: a
Out[40]: array([4, 4, 2, 1, 0, 3, 3, 1, 0, 2])

In [41]: a_unq, a_inv = np.unique(a, return_inverse=True)

In [42]: a_cnt = np.bincount(a_inv)

In [44]: np.cumsum(a_unq * a_cnt)[a_inv]
Out[44]: array([20, 20,  6,  2,  0, 12, 12,  2,  0,  6], dtype=int64)

もちろんa、配列が平坦化されている場所は、元の形状に再形成する必要があります。


もちろん、numpy 1.9 がリリースされたら、上記の 41 行目と 42 行目を 1 つにまとめて高速化できます。

a_unq, a_inv, a_cnt = np.unique(a, return_inverse=True, return_counts=True)
于 2014-05-14T20:02:31.287 に答える
1

これはどう:

a=np.array([ 4,  1  ,  3   ,  2])

np.array([np.sum(a[a<=x])for x in a])

与える

array([10,  1,  6,  3])

2D 配列の場合 (行だけでなく、配列全体の合計が必要であると仮定します):

a=np.array([[ 4,  1  ,  3   ,  2],[ 5,  1  ,  3   ,  2]])

np.array([[np.sum(a[a<=x])for x in a[y,:]]for y in range(a.shape[0])])

Gvies

array([[16,  2, 12,  6],
       [21,  2, 12,  6]])
于 2014-05-14T21:22:10.637 に答える
1

numpy が少なく、Python が多い場合:

a = np.array([[4,2,2,3],
              [9,0,5,2]], dtype=np.float32)

np.array([[sum(x for x in arr if x <= subarr) for subarr in arr] for arr in a])
# array([[ 11.,   4.,   4.,   7.],
#        [ 16.,   0.,   7.,   2.]])

アイテムがどれだけ表示されても合計がアイテムを 1 回しか考慮しない場合、

np.array([[sum(set(x for x in arr if x <= subarr)) for subarr in arr] for arr in a]) 
# array([[  9.,   2.,   2.,   5.],
#        [ 16.,   0.,   7.,   2.]])
于 2014-05-14T20:16:12.197 に答える