2016-11-19 7 views
3

リットルデジタル標高マップ、TIFFファイルを有し、Gdalモジュールとpandasを使用して、すべてのデータがdem.xlsxで書かれたファイルをエクセル、私の目的は、1で各行の最大値を交換することで、他の正の新しいセットで選択データを交換します値は0、負の値は-9999とし、結果を新しいExcelに書き込みます。しかし、私は値を置き換えて新しいExcelに書き込むことができませんでした。パンダは、

import pandas as pd 
import xlrd 
import xlsxwriter 
import gdal 

layer = gdal.Open(r"C:/Users/owrasa/PycharmProjects/den/dem/dem.tif") 
arr=layer.ReadAsArray() 
df=pd.DataFrame(arr) 

writer1 = pd.ExcelWriter(
    'dem.xlsx', engine='xlsxwriter') 
df.to_excel(writer1, 'Sheet1') 
writer1.save() 
df=pd.read_excel("dem.xlsx") 
writer2 = pd.ExcelWriter('output.xlsx',engine='xlsxwriter') 


for i in df: 
    for a in range(2851): 
     if i>0 and i<df.ix[a].max(): 
      df.replace(i,0) 
     elif i==df.ix[a].max(): 
      df.replace(i,1) 
     else: 
      df.replace(i,-9999) 

    df.to_excel(writer2, 'Sheet1') 
    writer2.save() 

DEMファイルは2098行のx 2851列を持つエクセル:

は、ここに私のコードです。

答えて

3

IIUCあなたはこのようにそれを行うことができます。

In [313]: df 
Out[313]: 
    a b c 
0 3 2 3 
1 -8 -5 8 
2 7 1 -7 
3 -4 -7 3 
4 -2 -10 0 

In [314]: df[df.ge(0)].fillna(-9999).where(df<0, df.eq(df.max(1), 0).astype(int)) 
Out[314]: 
     a  b  c 
0  1.0  0.0  1.0 
1 -9999.0 -9999.0  1.0 
2  1.0  0.0 -9999.0 
3 -9999.0 -9999.0  1.0 
4 -9999.0 -9999.0  1.0 

あなたが整数を必要とする場合:

In [320]: df[df.ge(0)].fillna(-9999).astype(int).where(df<0, df.eq(df.max(1), 0).astype(int)) 
Out[320]: 
     a  b  c 
0  1  0  1 
1 -9999 -9999  1 
2  1  0 -9999 
3 -9999 -9999  1 
4 -9999 -9999  1 

説明:

VirtualDF1:さんは-9999ですべての負の要素を置き換えてみましょう:

In [316]: df[df.ge(0)].fillna(-9999) 
Out[316]: 
     a  b  c 
0  3.0  2.0  3.0 
1 -9999.0 -9999.0  8.0 
2  7.0  1.0 -9999.0 
3 -9999.0 -9999.0  3.0 
4 -9999.0 -9999.0  0.0 

VirtualDF2:最後に、我々はVirtualDF1場合から要素を選択することができますDataFrame.where()方法を使用して

In [317]: df.eq(df.max(1), 0).astype(int) 
Out[317]: 
    a b c 
0 1 0 1 
1 0 0 1 
2 1 0 0 
3 0 0 1 
4 0 0 1 

と:我々はゼロを持つもの(1)および他の要素と、すべての行の最大値を置き換えることができ、このトリック(0)を使用して、元DFの対応する要素は...負のか、そうでなければVirtualDF2からである

2

これを行う方法があります。ただし、1点に注意してください。このコードでは、の最初のnanの値が置き換えられます。

# Create test data 
np.random.seed(0) 
df = pd.DataFrame(np.random.randint(-100,100,size=(100, 4)), columns=list('ABCD')) 

# Replace the max of each row for positive values by 1 
# Divide each value by the maximum of the row, in consequence: 
# - the max is = 1 
# - negative values are nan since they have been filtered 
# - Remaining values are in the [0, 1[ interval 
df = df[df>0].apply(lambda x: x/x.max(), axis=1) 

# Replace remaining positive values by 0 
df[df<1] = 0 

# Replace negative values (nan) by -9999 
df = df.fillna(-9999) 

# Write the result to an Excel sheet 
writer = pd.ExcelWriter('output.xlsx') 
df.to_excel(writer,'result') 

# Before 
# A B C D 
# 0 72 -53 17 92 
# 1 -33 95 3 -91 
# 2 -79 -64 -13 -30 
# 3 -12 40 -42 93 
# 4 -61 -13 74 -12 

# After 
#   A  B  C  D 
# 0  0.0 -9999.0  0.0  1.0 
# 1 -9999.0  1.0  0.0 -9999.0 
# 2 -9999.0 -9999.0 -9999.0 -9999.0 
# 3 -9999.0  0.0 -9999.0  1.0 
# 4 -9999.0 -9999.0  1.0 -9999.0 
+0

== '0'のx/x.max() ''場合x.max()に起こるのだろうか? – MaxU

+0

私はあなたのコードを試しましたが、いくつかの行に2つ以上の最大値があるので、結果は満足のいくものではありません。 –

+0

@MaxU Oups、私はそれがバグだと思います、この場合は 'nan'を生成します。 @ömersarı元のデータセットに等しい最大値を持つ行の場合に期待されることは理解できません。どのようにしてそれらの間で選択できますか? MaxUが提供する答えを使うべきだと思います。 – Romain

4

試してみてください。

df.eq(df.max(1), 0).sub(df.lt(0).mul(9999)) 

enter image description here

+1

! – MaxU

+0

しかし、上の例のように2つの最大値がない場合、同じ行に2つの最大値があります.lループが使用されているのは間違っていますか?または構造が適切ではない? –