Pandas用新的集合替换选择性数据

时间:2016-11-19 21:45:51

标签: python pandas dataframe

我有一个数字高程图Tiff文件,并使用Gdal模块和pandas,所有数据都写在dem.xlsx excel文件中,我的目的是替换每行的最大值使用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 excel文件有2098行x 2851列。

3 个答案:

答案 0 :(得分:4)

尝试:

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

enter image description here

答案 1 :(得分: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:使用此技巧,我们可以将所有行的最大值替换为1(1),将其他元素替换为零(0):

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

最后使用DataFrame.where()方法我们可以选择VirtualDF1中的元素,如果原始DF中的对应元素是负数,或者来自VirtualDF2,否则......

答案 2 :(得分:2)

这是一种方法。但是,请注意一点,此代码将使用nan替换初始-9999值。

# 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