zoukankan      html  css  js  c++  java
  • Pandas 批量处理文本表

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

    但涉及一些数据的安全, 和指标这块也是不能透露的, 因此只能是贴上代码, 目的还是给自己以后做参考的. 代码中有个常数, 其实表示每个文件, 每行的同位置的值, 是一样的. 是发现规律了, 最开始是找近似, 去最为接近的一条, 后来写完发现, 根本不用不动. 然后, 文本数据, 就是后缀不是常用的, 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 这样产生对比.
  • 相关阅读:
    IE浏览器cookie存放在本地什么目录
    C# clickonce 部署自定义文件
    [C#.Net]C#连接Oracle数据库的方法
    Eclipse 插件一览
    登录名 '***' 拥有一个或多个数据库。在删除该登录名之前,请更改相应数据库的所有者。 (Microsoft SQL Server,错误: 15174)
    SqlServer_表结构查询_查询当前用户所有表名
    sqlserver怎么删除有外键关联的数据?
    springboot logback控制台中文输出乱码
    控制台运行JAVA的jar文件时乱码 / Gradle编译设置编码格式
    Python 算法之一
  • 原文地址:https://www.cnblogs.com/chenjieyouge/p/12977516.html
Copyright © 2011-2022 走看看