在xcel到制表符分隔文件转换期间将Float转换为整数

时间:2015-01-07 19:37:58

标签: python casting xlrd

我编写了以下方法,将.xlsx文件转换为.txt制表符分隔文件。

import sys
import xlrd
import csv

def xlsx_to_tab(self, inFile):
    ''' Convert an xlsx file to a tab delimited file. '''
    excel_file = xlrd.open_workbook(inFile)
    worksheet = excel_file.sheet_names()[0]
    sh = excel_file.sheet_by_name(worksheet)
    extentPos = inFile.rfind('.')
    tab_file = open(inFile[:extentPos] + '.txt', 'w')
    writetab = csv.writer(tab_file, delimiter='\t', quoting=csv.QUOTE_ALL)

    for row in range(sh.nrows):
        writetab.writerow(sh.row_values(row))

    tab_file.close()

此方法在文件格式之间成功转换,但是,原始excel文件中看似整数的内容在.txt文件输出中作为浮点输出。

我知道这可能与excel中的单元格格式设置有关。话虽这么说,我想在这个脚本中处理这个,因为我想明确地将文件中的元素定义为int()的整数,而不是先检查和更改所有excel文件,这将是乏味的。

此方法逐行处理文件。有没有办法检索每一行中的单个元素,以便键入将它们转换为整数?

This question解决了这个问题:

但是显示了如何一次为一个值而不是整列值进行操作。

为了更清楚一点,我试图将单个列转换为整数但不是全部。因此,只需要转换每行的某些元素。

数字列是列1,3和5

3 个答案:

答案 0 :(得分:1)

使用list comprehension将行的元素转换为int,然后再将它们写入新文件:

for row in range(sh.nrows):
    new_row = [int(x) for x in sh.row_values(row)]
    writetab.writerow(new_row)
编辑:根据OP的新评论,你需要做的事情(虽然不是很漂亮)是:

int_columns = [1, 3, 5]
for row in range(sh.nrows):
    new_row = sh.row_values(row)
    for col in int_columns:
        new_row[col] = int(new_row[col])
    writetab.writerow(new_row)

我建议你改一下你的命名。在最外层循环中,您将迭代整数,但您将变量命名为row。我会这样写:

int_columns = [1, 3, 5]
for i in range(sh.nrows):
    row = sh.row_values(i)
    for col in int_columns:
        row[col] = int(new_row[col])
    writetab.writerow(row)

答案 1 :(得分:1)

你可以这样做:

for row in range(sh.nrows):
    new_row = [int(x) if i in {1,3,5} else x for i, x in
        enumerate(sh.row_values(row), start=1)]
    writetab.writerow(new_row)

答案 2 :(得分:0)

也可以考虑这个来检查单元格是浮点/整数/文本,并使用 map 将其转换为自定义函数,如下所示:

def convert_int_or_string(n):
    try:
        float(n)
        assert str(n).lower() != 'nan'
        return int(float(n))
    except (ValueError, AssertionError):
        return n

test_row 
['3.14',
 'nan',
 '12.143141234',
 'hello',
 '0.13989402028',
 'world',
 '0.26575558139',
 '11',
 '0.919189932407',
 '!']

map(convert_int_or_string, test_row)
[3, 'nan', 12, 'hello', 0, 'world', 0, 11, 0, '!']

在您的模块中添加此convert_int_or_string功能,并将此行更改为:

writetab.writerow(map(convert_int_or_string, sh.row_values(row)))