在2d数组中排列不同数量的浮点数

时间:2015-11-29 10:08:06

标签: python arrays

首先,我是蟒蛇的新手,所以请原谅我,如果我不看树木。我的问题是读取一个巨大的浮点数文件并将它们存储在一个数组中,以便进行快速的数学后处理。

让我们假设文件看起来类似于:


/**
 * This is the first stage bootloader. It is used to loader the second
 * stage bootloader.
 */



# The address of this bootloader been loaded by BIOS
.equ BOOTLOADER_ADDR, 0x07c0

# The signature for bootloader.
.equ BOOT_MACHINE_SIGNATURE, 0xaa55

# The offset of the start of BPB (BIOS Parameter Block).
.equ BOOT_MACHINE_BPB_START, 0x03

# The offset of the end of BPB (BIOS Parameter Block).
.equ BOOT_MACHINE_BPB_END, 0x5a

# The offset of the end of the partition table.
.equ BOOT_MACHINE_PART_END, 0x1fe

/* The segment of disk buffer. The disk buffer MUST be 32K long and
   cannot straddle a 64K boundary.  */
.equ BOOT_MACHINE_BUFFER_SEG, 0x7000

.macro PRINT str
        pusha
        movw $\str, %si
        call print
        popa
.endm

.macro DUMP begin, size
        movw $\begin, %si
        movw $\size, %cx
        call dump
.endm

.macro RESET_DISK drive
        pusha
        movb $\drive, %dl
        movw 0x0, %ah
        call reset_disk
        popa
.endm

.macro READ_SECTORS drive, head, cylinder, sector, count, destination
        pusha
        movw $\destination, %ax
        movw %ax, %es
        xorw %bx, %bx
        movb $\drive, %dl
        movb $\head, %dh
        movb $\cylinder, %ch
        movb $\sector, %cl
        movb $\count, %al
        call read_sectors
        popa
.endm

/**
 * Entry point
 */
        .file "boot.S"
        .text
        .code16
        .org 0x0000
.globl _start, start;
_start:
start:
# The offset 0x0000 must be a jump to the reset of code.
        jmp after_BPB
        nop
        . = _start + BOOT_MACHINE_BPB_START
        . = _start + 4
disk_addr_packet:
        .byte 0x10              # (00h) size of packet
        .byte 0x00              # (01h) reserved
        .word 0x0001            # (02h) number of blocks to transfer
        .word 0x8000, 0x0000    # (04h) DWORD, transfer buffer
        .word 0x0010, 0x0000    # (08h) QWORD, starting absolute block number
        .word 0x0000, 0x0000
                                # (10h)
        . = _start + BOOT_MACHINE_BPB_END
after_BPB:
        cli                             # disable interrupt.
        movw $BOOTLOADER_ADDR, %ax      # set address expression
        movw %ax, %ds
        movw %ax, %es
        # movw $BOOTLOADER_ADDR, %sp    # stack grows down to 0x0000
        PRINT message_booting

# We need make sure the BIOS supports the INT 13 extensions.
int13_ext_check:
        mov $0x41, %ah
        mov $0x55aa, %bx
        # DL should contain the drive value. But we'd better save it.
        push %dx
        int $0x13
        jc int13_ext_check_failed
        cmpw $0xaa55, %bx
        jne int13_ext_check_failed
        andw $0x001, %cx        # if function 42h-44h,47h,48h are supported
        jz int13_ext_check_failed
        jmp read_cd_content

int13_ext_check_failed:
        PRINT message_no_int13_ext
        jmp loop

read_cd_content:

        # CHS mode : Cylinder-Head-Sector mode.
        # LBA mode : Logical Block Addressing mode.
        # When we use INT 13 extension, we use LBA mode in which
        # the device is taken as a single large device.

        PRINT message_loading_img
        pop %dx
        movw $disk_addr_packet, %si
        movb $0x42, %ah
        int $0x13
        jc error_read_sectors

        DUMP 0x0400, 16
        jmp loop

error_read_sectors:
        PRINT message_sector_read_err
        jmp loop
loop:
        PRINT message_halt
        cli
        hlt
        jmp loop
message_booting:
        .asciz "Booting ...\r\n"
message_halt:
        .asciz "Boot Halt.\r\n"
message_no_int13_ext:
        .asciz "No INT13 extension. Boot failed.\r\n"
message_loading_img:
        .asciz "Loading OS image.\r\n"
message_sector_read_err:
        .asciz "Sector read error.\r\n"
hexdump:
        .byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08

/**
 * Write the string pointed to by %si
 * Each char is wrote by using BIOS INT 0x10.
 * BIOS INT 0x10:
 * AH = 0x0e
 * AL = Character to write.
 * BH = Page Number (Should be 0)
 * BL = Foreground color (Graphics Modes Only)
 * When using the function, put the string address to SI. The string
 * should end with 0.
 */
1:
        movw $0x0001, %bx
        movb $0xe, %ah
        int $0x10
print:
        lodsb   # Loads a byte pointed by SI into AL.
        cmpb $0, %al
        jne 1b
        ret

/**
 * Print the register's value.
 *
print_reg:

/**
 * Dump a area of data.
 * Display 8 bytes of code each line. For every 10 line will wait for any key to continue.
 * SI = The start address
 * CX = The size of area to dump
 */
index:
.byte '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
.byte 'A', 'B', 'C', 'D', 'E', 'F'
enter_key:
.asciz "\r\n"
1:
        ret
dump:
        movb $10, %dl           # DL = row counter, DH = column counter.
        movb $8, %dh
        cld
2:
        cmpw $0, %cx
        je 1b
        xorw %ax, %ax           # clean the AX at first.
        lodsb                   # loads the byte pointed by SI into AL.
        push %ax                # because AH will be used, so we save AX.
        shr $4, %ax             # show first 4 bits.
        movw $index, %di
        addw %ax, %di
        movb (%di), %al
        movb $0xe, %ah
        movw $0x0001, %bx       # Page number = 0, froeground color = 1.
        int $0x10
        pop %ax
        andw $0x000f, %ax       # show last 4 bits.
        movw $index, %di
        addw %ax, %di
        movb (%di), %al
        movb $0xe, %ah
        movw $0x0001, %bx
        int $0x10
        movb $' ', %al          # display a space
        movb $0xe, %ah
        movw $0x0001, %bx
        int $0x10
        dec %cx
        dec %dh
        jnz 2b
        PRINT enter_key
        movb $8,%dh
        jmp 2b

/**
 * Reset the disk controller, let it go to the first sector.
 * BIOS INT 0x13
 * AH = 0x00
 * DL = Drive to reset.
 * Return:
 * AH = Status code.
 * CF = Clear if success, set if failure.
 */
reset_disk:
        int $0x13
        jc reset_disk
        ret

/**
 * Read sectors into memory
 * BIOS INT 0x13
 * AH = 0x02
 * AL = Numbers of sectors to read.
 * CH = Low eight bits of cylinder number.
 * CL = Sector Number Bits 0-5. Bits 6-7 are for hard disks only.
 * DH = Head number.
 * DL = Drive number (Bit 7 set for hard disk)
 * ES:BX = Buffer to read sector to
 * Return
 * AH = Status code
 * AL = Number of sectors read
 * CF = Set if failure, cleaned if successful.
 */
read_sectors:
        int $0x13
        jc read_sectors
        ret

        .fill 0x1fe - (. - _start) ,1,0
        .org _start + BOOT_MACHINE_PART_END
        .word BOOT_MACHINE_SIGNATURE

这里有4(nb)个14(nk)个浮点数。我希望它们被安排在数组元素[nb] [nk]中,以便我可以轻松地访问块的某些浮点数。

以下是我认为的样子,但它根本不起作用:

!!
    -3.2297390   0.4474691   3.5690145   3.5976372   6.9002712   7.7787466  14.2159269  14.3291490
    16.7660723  17.1258704  18.9469059  19.1716808  20.0700721  21.4088414
    -3.2045361   0.4123081   3.5625981   3.5936954   6.8901539   7.7543415  14.2764611  14.3623976
    16.7955934  17.1560337  18.9527369  19.1251184  20.0700709  21.3515145
    -3.2317597   0.4494166   3.5799182   3.6005429   6.8838705   7.7661897  14.2576455  14.3295731
    16.7550357  17.0986678  19.0187779  19.1687722  20.0288587  21.3818250
    -3.1921346   0.3949598   3.5636878   3.5892085   6.8833690   7.7404542  14.3061281  14.3855389
    16.8063645  17.1697110  18.9549920  19.1134580  20.0613223  21.3196066

如果有一些想法和建议会很棒。谢谢!

编辑:

这里是一个数据文件,其中数字跟在一起,在块nb后没有明确的分隔符。这里是nb = 2且nk = 160。如何在每个第160个数字后拆分浮点数?

nb=4
nk=14

with open("datafile") as file:
    elements = []
    n = 0    
    while '!!' not in file: 
            while n <= (nb-1):
            elements.append([])
            current = map(float,file.read().split())  # here I would need something to assure only 14 (nk) floats are read in
            elements[n].append(current)
            n += 1

print(elements[0][1])

1 个答案:

答案 0 :(得分:1)

这应该有效:

elements = []
with open("datafile") as file:
    next(file)
    for line in file:
        elements.append([float(x) for x in line.split()])

next(line)读取第一行。然后for line in file:遍历所有其他行。列表推导[float(x) for x in line.split()]遍历由空格分割的行中的所有条目。最后,elements.append()将此列表附加到elements,这将成为您可以称为2D数组的列表列表。

访问第一行中的第一个条目:

>>> elements[0][0]
-3.229739

或最后一行中的最后一个条目:

>>> elements[3][13]
21.319606

或者:

>>> elements[-1][-1]
21.319606

更新

这会将文件读入列表列表,而不会将换行符视为特殊符号:

nb = 2
nk = 160

with open("datafile") as fobj:
    all_values = iter(x for x in fobj.read().split())
    next(all_values)
    elements = []
    for x in range(nb):
        elements.append([float(next(all_values)) for counter in range(nk)])

如果您喜欢嵌套列表推导:

with open("datafile") as fobj:
    all_values = iter(x for x in fobj.read().split())
    next(all_values)
    elements = [[float(next(all_values)) for counter in range(nk)] for x in range(nb)]