elsiwaveQI 2024-10-09 14:11 采纳率: 64%
浏览 25
已结题

python写segy数据时出错2

#遇到问题的现象描述
任务是写segy数据到指定目录。首先读取segy中关键信息,然后构建存放关键参数如text、bin、iline、xline等的local_f_data字典文件,以及sepc文件。已经检查过关键参数符合要求,程序运行到写segy数据时报错。请检查代码段中错误并给予修改后的代码,谢谢!

#问题相关代码片,运行结果,报错内容
相关代码片段:


        print("开始创建字典")
        local_f_data = {
            'text': text,
            'bin':{
                segyio.BinField.Samples: samples,
                segyio.BinField.Interval: interval,  # Sampling interval (milliseconds)
                segyio.BinField.Format: dataformat
            },
            'tracecount': tracecount, #len(self.traces), 确保你在这里计算 trace 的数量
            'iline': iline,  
            'xline': xline
        }

        print("构建spec")
        spec = segyio.spec()
        spec.samples = samples  # 样本点数量,确保其为整数
        #spec.samples = len(local_f_data['bin'][segyio.BinField.Samples])  # 确保这是一个整数
        spec.format = dataformat #已经修改为常量或枚举
        spec.tracecount = tracecount  # 确保 tracecount 是整数
        spec.interval = interval
        spec.iline = np.unique(iline).astype(np.int32) if iline is not None else None
        spec.xline = np.unique(xline).astype(np.int32) if xline is not None else None
...
        print(f"Attempting to open SEGY file: {self.output_file}")

        #print(self.local_f_data['text'])
        #print(self.local_f_data['bin'])
        print(self.spec.samples) #证实单个整数,751
        print(self.spec.interval)#证实单个整数,4000
        print(self.spec.format)#证实单个整数,1
        print(self.spec.iline)#一维整数numpy数组
        print(self.spec.xline)#一维整数numpy数组
        print(self.spec.tracecount)#证实单个整数,9911
        
        try:    
            # Create SEGY file with spec
            with segyio.create(self.output_file, self.spec) as w:
                print('开始写文本头') # 程序没有执行这行,说明错误发生在这行之前
                text_data = self.local_f_data['text'][0].encode('utf-8')[:3200]
                w.text[0] = text_data.ljust(3200, b' ')  # 填充到 3200 字节

运行结果:
MainWindow initialized
Application started
Save button clicked
开始创建字典
bytearray(b'C 1 CLIENT COMPANY CREW NO.
C 2 LINE AREA MAP ID.
C 3 REEL NO. DAY-START OF REEL YEAR OBSERVER
C 4 INSTRUMENT: MFG MODEL SERIAL NO.
C 5 DATA TRACES/RECORD AUXILIARY TRACES/RECORD CDP FOLD
C 6 SAMPLE INTERVAL MS SAMPLES/TRACE BITS/IN BYTES/SAMP
LE C 7 RECORDING FORMAT FORMAT THIS REEL MEASUREMENT SYSTEM
C 8 SAMPLE CODE: FLOATING PT FIXED PT FIXED PT-GAIN CORR
ELATED C 9 GAIN TYPE: FIXED BINARY FLOATING POINT OTHER
C10 FILTERS: ALIAS HZ NOTCH HZ BAND HZ SLOPE
C11 SOURCE: TYPE NUMBER/POINT POINT INTERVAL
C12 PATTERN LENGTH WIDTH
C13 SWEEP: START HZ END HZ LENGTH MS CHANNEL NO. T
YPE C14 TAPER: START LENGTH MS END LENGTH MS TYPE
C15 SPREAD: OFFSET MAX DISTANCE GROUP INTERVAL
C16 GEOPHONES: PER GROUP SPACING FREQUENCY MFG MODEL
C17 PATTERN LENGTH WIDTH
C18 TRACES SORTED BY: RECORD CDP OTHER
C19 MAP PROJECTION ZONE ID COORDINATE UNITS
C20 BEGINNING SHOTPOINT (OBSERVER-S):
C21 ENDING SHOTPOINT (OBSERVER-S):
C22 DIRECTION OF LINE:
C23 COUNTY STATE SURVEY NO.
C24
C25
C26
C27
C28
C29
C30
C31
C32
C33
C34
C35
C36
C37
C38
C39
C40
{3221: 751, 3217: 4000, 3225: 1}
9911
[1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070]

构建spec
打印调试
751
9911
4000
1
检查samples是否为一整数
Spec Samples: 751
Type of Spec Samples: <class 'int'>
Thread started
Attempting to open SEGY file: D:/ML/mldata/plot_project/deeplearning/output.sgy
751
4000
1
[1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070]

9911
Error while writing SEGY file: len() of unsized object
Thread finished

报错信息:
Error while writing SEGY file: len() of unsized object

  • 写回答

22条回答 默认 最新

  • 杨同学* 2024-10-09 15:10
    关注

    该回答引用ChatGPT4o及杨同学*共同作答, 如有帮助,还请采纳。
    根据你提供的报错信息以及代码段,错误提示为 **len() of unsized object**,这意味着代码试图对一个没有长度的对象调用 len() 函数。通常这是因为在某些情况下,程序期望一个可以计算长度的对象(如列表、数组等),但却得到了非集合类型(如整数或 None)。

    从报错信息和你的代码片段中,问题可能出现在构建 spec 的过程中。特别是在处理 ilinexline 时,它们的 numpy 数组可能未正确初始化,或其数据不符合预期。为了更好地诊断和解决这个问题,我们可以做如下调整。

    代码修改建议

    1. spec.ilinespec.xline 的处理:
      确保 ilinexline 是有效的一维整数 numpy 数组。并且在创建 spec 时,要确保这些字段是有意义的,否则可能会导致写 SEGY 文件时出现问题。

    2. 确认 samplesintervaltracecount 等关键字段都是整数:
      从你调试信息来看,这些字段似乎已经是整数,但我们还是需要确保这些值在传递过程中不发生变化。

    修改后的代码片段

    print("开始创建字典")
    local_f_data = {
        'text': text,
        'bin': {
            segyio.BinField.Samples: samples,
            segyio.BinField.Interval: interval,  # Sampling interval (milliseconds)
            segyio.BinField.Format: dataformat
        },
        'tracecount': tracecount,  # 确保 tracecount 是整数
        'iline': iline,
        'xline': xline
    }
    
    print("构建spec")
    spec = segyio.spec()
    spec.samples = samples  # 样本点数量, 确保其为整数
    spec.format = dataformat  # 数据格式
    spec.tracecount = tracecount  # 确保 tracecount 是整数
    spec.interval = interval  # 采样间隔
    
    # 处理 iline 和 xline,确保它们为非空的 numpy 整数数组
    if iline is not None and len(iline) > 0:
        spec.iline = np.unique(iline).astype(np.int32)  # 确保为整数数组
    else:
        raise ValueError("Invalid iline: it must be a non-empty numpy array.")
    
    if xline is not None and len(xline) > 0:
        spec.xline = np.unique(xline).astype(np.int32)  # 确保为整数数组
    else:
        raise ValueError("Invalid xline: it must be a non-empty numpy array.")
    
    # 打印调试信息
    print("打印调试")
    print(f"Samples: {spec.samples}")
    print(f"Interval: {spec.interval}")
    print(f"Format: {spec.format}")
    print(f"Iline: {spec.iline}")
    print(f"Xline: {spec.xline}")
    print(f"Tracecount: {spec.tracecount}")
    
    # 尝试创建 SEGY 文件
    try:
        print(f"Attempting to open SEGY file: {self.output_file}")
    
        # 使用 spec 创建 SEGY 文件
        with segyio.create(self.output_file, spec) as w:
            print('开始写文本头')
            
            # 检查 text 数据并将其转换为 bytearray
            text_data = self.local_f_data['text'][0].encode('utf-8')[:3200]
            w.text[0] = text_data.ljust(3200, b' ')  # 确保填充到 3200 字节
            
            print('SEGY 文件写入完成')
    
    except Exception as e:
        print(f"Error while writing SEGY file: {str(e)}")
    

    主要修改内容

    1. spec.ilinespec.xline 的非空检查:

      • 在将 ilinexline 传递给 spec 之前,确保它们不是空的 numpy 数组。如果为空,则抛出错误并终止程序执行。这能避免 len() 函数无法对空对象调用的情况。
    2. 增加调试信息:

      • 在写入 SEGY 文件之前,打印了更多的调试信息以确保所有关键字段已经正确设置并且类型符合要求。
    3. 异常处理:

      • 增加了对异常的捕获并输出错误消息,以便更好地诊断问题。

    总结

    问题的关键在于检查传递给 specilinexline 是否为空或者类型是否正确。经过修改后,代码会检查它们是否为空或不合规,从而避免 len() 的调用出错。如果问题仍未解决,可以进一步检查输入数据的结构和格式是否符合预期。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(21条)

报告相同问题?

问题事件

  • 系统已结题 10月18日
  • 已采纳回答 10月10日
  • 创建了问题 10月9日