Pandas 批量处理文本表

jiahaohappy 2020-05-28

就是一个批量读取文件, 然后计算指标的过程. 难度到是没啥, 只是想记录一把, 毕竟这类的需求, 其实还是蛮多的.

但涉及一些数据的安全, 和指标这块也是不能透露的, 因此只能是贴上代码, 目的还是给自己以后做参考的. 代码中有个常数, 其实表示每个文件, 每行的同位置的值, 是一样的. 是发现规律了, 最开始是找近似, 去最为接近的一条, 后来写完发现, 根本不用不动. 然后, 文本数据, 就是后缀不是常用的, Excel, Csv.. 这种, 给我有个 xx.sed 从未见过的这类. 还好我基本功可以, 毕竟当年抄过书本, read_table 这类的骚操作, 就恰好满足需求了.

因为涉及的数据不能公开, 业务这块也不能谈及, 指标计算比较多和杂. 总之是给我自己看的, 并未作为分享的.

from os import listdir
import pandas as pd
from math import log10
import time

# 发现数据规律, 每个文件的第一列值 Wvl 都是固定的, 直接取即可
# 每个指标值行索引(Wvl)可以先全部找出来
R990 = 990.4
R720 = 719.5
R860 = 860.2
R790 = 789.7
R670 = 669.4
R730 = 730.2
R525 = 525.2
R750 = 749.9
R705 = 704.8
R445 = 444.5
R550 = 550.1
R870 = 869.5
R680 = 680.3
R810 = 809.7
R800 = 799.7
R700 = 699.4
R840 = 840.1
R1510 = 1511.8
R1680 = 1681.2

start = time.time()

ret = []  # 结果

my_dir = ‘./光谱数据集/‘
file_list = listdir(my_dir)
for cur_file in file_list:
    print("正在处理:", cur_file)
    df = None
    try:
        df = pd.read_table(my_dir + cur_file, skiprows=26)
        # df[‘nb‘] = df[‘Raw Counts (Ref.)‘] - df[‘Raw Counts (Target)‘]
        df[‘nb‘] = round(df[‘Reflect. %‘] / 100, 2)
        df = df.set_index(‘Wvl‘)[‘nb‘]
    except Exception as e:
        print("出错啦, 大兄弟!", e)

    # 计算着一大坨数据指标
    cur_lst = []
    # 被文件名作为 第一个数据
    cur_lst.append(cur_file)
    # RSI
    rsi = df.loc[R990] / df.loc[R720]
    cur_lst.append(rsi)

    # NDSI
    ndsi = (df.loc[R860] - df.loc[R720]) / (df.loc[R860] + df.loc[R720])
    cur_lst.append(ndsi)

    # FD_NDVI
    fdndvi = (df.loc[R730] - df.loc[R525]) / (df.loc[R730] + df.loc[R525])
    cur_lst.append(fdndvi)
    # RENDVI
    cur_lst.append((df.loc[R750] - df.loc[R705]) / (df.loc[R750] + df.loc[R705]))
    # mNd705
    cur_lst.append((df.loc[R750] - df.loc[R705]) / (df.loc[R750] + 2 * df.loc[R445]))
    # GNDVI
    cur_lst.append((df.loc[R790] - df.loc[R550]) / (df.loc[R790] + df.loc[R550]))
    # SAVI
    cur_lst.append(1.5 * (df.loc[R870] - df.loc[R680]) / (df.loc[R870] + df.loc[R680] + 0.16))
    # OSIVI
    cur_lst.append(1.16 * (df.loc[R810] - df.loc[R680]) / (df.loc[R810] - df.loc[R680] + 0.16))
    # MSAVI
    cur_lst.append(
        2 * (df.loc[R800] + 1 - ((2 * df.loc[R800] + 1) * 2 - 8 * (df.loc[R800] - df.loc[R670])) * 0.5)
    )
    # DCNA
    cur_lst.append(
        (df.loc[R720] - df.loc[R700]) / (df.loc[R700] - df.loc[R670]) / (df.loc[R700] - df.loc[R670] + 0.03)
    )
    # CIgreen
    cur_lst.append(((df.loc[R840] - df.loc[R870]) / df.loc[R550]) - 1)
    # NINI
    try:
        cur_lst.append(
            (log10(1 / df.loc[R1510]) - log10(1 / df.loc[R1680])) / (log10(1 / df.loc[R1510]) + log10(1 / df.loc[R1680]))
        )
    except:
        print(cur_file, "log 计算有问题")
        cur_lst.append(‘lg计算失败‘)
    # TVI
    cur_lst.append(
        0.5 * (120 * (df.loc[R750] - df.loc[R550]) - 200 * (df.loc[R670] - df.loc[R550]))
    )
    # DSI
    cur_lst.append(df.loc[R800] - df.loc[R680])

    # 将当前结果添加到 ret 中
    ret.append(cur_lst)

# 最后将 [[],[]...] 再存为 DataFrame
col = [‘数据文件名‘, ‘RSI‘, ‘NDSI‘, ‘FD_NDVI‘, ‘RENDVI‘, ‘mNd705‘, ‘GNDVI‘, ‘SAVI‘,
       ‘OSIVI‘, ‘MSAVI‘, ‘DCNA‘, ‘CIgreen‘, ‘NINI‘, ‘TVI‘,‘DSI‘]

data = pd.DataFrame(ret,
                    columns=col)
print()
print("*"*50)
print("正在存储到,  表格...")

data.to_excel("D:/光谱数据.xlsx", index=False)

end = time.time()
print(f"处理完毕! 共处理 {len(file_list)} 个文件,  总共用时 {round(end - start, 2)} 秒")
print("*"*50)

其实蛮简单的一个脚本, 循环读取文件夹的数据, 然后来弄即可. 发现现在这换了 台式电脑, 果然很稳, 同时 读取 文本数据, 远比 Excel 文件, 效率高了 近 10倍.

正在处理: 20190930_00128.sed
正在处理: 20190930_00129.sed
正在处理: 20190930_00130.sed
正在处理: 20190930_00131.sed
正在处理: 20190930_00132.sed
正在处理: 20190930_00133.sed
正在处理: 20190930_00134.sed
正在处理: 20190930_00135.sed
正在处理: 20190930_00136.sed
正在处理: 20190930_00137.sed
正在处理: 20190930_00138.sed
正在处理: 20190930_00139.sed
正在处理: 20190930_00140.sed
正在处理: 20190930_00141.sed
正在处理: 20190930_00142.sed
正在处理: 20190930_00143.sed
正在处理: 20190930_00144.sed
正在处理: 20190930_00145.sed
正在处理: 20190930_00146.sed
正在处理: 20190930_00147.sed
......

**************************************************
正在存储到,  表格...
处理完毕! 共处理 1447 个文件,  总共用时 5.58 秒
**************************************************
[Finished in 6.1s]
  • 经常谈什么批量处理文件, 其实就是, 结构化的, 对单个文件, 逻辑写好, 然后循环处理 n 多个文件.
  • 对指标计算, 设计好号数据结构, 列表, 字典这些, 最好是用 生成器 yield 来弄, 最后再 list 出来, 提高性能
  • 3年多了, 真实觉得 Pandas 是真的好用哇, 尤其是处理方面, 主要是现在很多逻辑, 是通过 sql 这样产生对比.

相关推荐