【问题标题】:Python--Read dat file rows, rewrite to columns in Excel. csv/numpy/openpyxlPython--读取 dat 文件行,重写 Excel 中的列。 csv/numpy/openpyxl
【发布时间】:2020-07-07 21:02:44
【问题描述】:

我在使用 csv/numpy/openpyxl 时遇到了一些问题,问题是 我有一个 .dat 文件,在

a,a,a,a
b,b,b,b
c,c,c,c

我要取dat文件的每一行,每个excel放到一列,意思是

excel文件:

a b c
a b c
a b c

这是我到目前为止所做的:

import csv
import openpyxl
import numpy as np


wb = openpyxl.Workbook()
ws = wb.active

with open('Shari10.dat') as f:
    dat_reader = csv.reader(f, delimiter = ",")

    for header in csv.reader(f):
        break

    for dat_line in f:
        line = dat_line.split(",")

        data = np.vstack(line[1:8])

        for row in data:
            ws.append(row)
            print(row)
        #wb.save("coffee.xlsx")

这是错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-a07e6ac6842f> in <module>
     20         print(data)
     21         for row in data:
---> 22             ws.append(row)
     23         #wb.save("coffee.xlsx")

~\AppData\Local\Continuum\anaconda3\lib\site-packages\openpyxl\worksheet\worksheet.py in append(self, iterable)
    665 
    666         else:
--> 667             self._invalid_row(iterable)
    668 
    669         self._current_row = row_idx

~\AppData\Local\Continuum\anaconda3\lib\site-packages\openpyxl\worksheet\worksheet.py in _invalid_row(self, iterable)
    792     def _invalid_row(self, iterable):
    793         raise TypeError('Value must be a list, tuple, range or generator, or a dict. Supplied value is {0}'.format(
--> 794             type(iterable))
    795                         )
    796 

TypeError: Value must be a list, tuple, range or generator, or a dict. Supplied value is <class 'str'>

作为参考,我试图这样做:

data = [
         ['A', 100, 1.0],
         ['B', 200, 2.0],
         ['C', 300, 3.0],    
         ['D', 400, 4.0],        
 ]
for row in data:
    ws.append(row)

同时,我刚开始学习python,请原谅我乱七八糟的代码结构,至于语法,我尽量写得准确而不是缩短代码。

【问题讨论】:

    标签: python excel numpy csv openpyxl


    【解决方案1】:

    您似乎遇到了一些问题,即 numpy 数组不是列表。您可以通过使用 numpy 的 tolist() 方法来解决这个问题

    for row in data:
        ws.append(row)
        print(row)
    

    到这里

    for row in data:
        ws.append(row.tolist())
        print(row.tolist())
    

    仅更改这些行将使代码成功运行,但它不会提供您想要的输出。使用输入文件运行代码

    a,a,a,a
    b,b,b,b
    c,c,c,c
    

    生成一个如下所示的电子表格,因为您将每个行数组转置为一个列数组,然后将各列堆叠在一起(ws.append 将行添加到工作表的底部)

    b
    b
    b
    b\n
    c
    c
    c
    c\n
    

    如果您希望转置整个 csv(包括标题),一个简单的方法是使用 numpy 的 transpose 方法。此方法将为您交换整个数组,然后您可以遍历每一行以将它们中的每一个写入工作表。这将简化您在 csv 文件中的读取方式,如下所示。请记住 transpose 仅适用于方形数组,因此我添加了一些代码来对任何锯齿状数组进行平方。

    import openpyxl
    import numpy as np
    
    # Create 
    wb = openpyxl.Workbook()
    ws = wb.active
    
    with open('input.dat') as f:
        # Read in all the data
        data = list(csv.reader(f))
    
        ## If your CSV isn't square, you need to square it first
        # Get longest row in array
        longest = len(max(data, key=len))
        # Pad every row to longest row length
        for row in data:
            row.extend( (longest - len(row))*[''])
    
        ## Once data is square, continue as normal
        # Transpose the array
        data = np.transpose(data)
    
        # Write all rows to worksheet
        for row in data:
            ws.append(row.tolist())
    
    # Save worksheet
    wb.save('test.xlsx')
    

    【讨论】:

    • erro-'list' 对象没有属性 'tolist' 知道吗? :)
    • 这只适用于你的数组是正方形的(每一行都有相同数量的元素)。我正在寻找一种更好的方法来快速处理锯齿状数组。我不确定 Chicodelarosa 的答案是否适用于锯齿状数组
    • 我设法让它适用于锯齿状数组,现在正在编辑我的答案以支持它。让我知道它是否有效
    • 效果很好!让我研究一下,因为我需要恭敬地填写特定列的单元格,我以后可以问你吗?
    • 您可能需要仔细检查您的 CSV 是否能够呈锯齿状,因为缺少字段可能会导致电子表格出现问题。如果您的电子表格可能缺少字段,那么这将起作用
    【解决方案2】:

    假设我们有一个文件 example.dat,其内容如下:

    a1,a2,a3,a4
    b1,b2,b3,b4
    c1,c2,c3,c4
    

    最好使用 pandas。首先将数据加载为 dataframe,然后进行 transpose 并将生成的 dataframe 保存在 excel 文件中,如下所示:

    import pandas as pd
    
    df_in = pd.read_csv("example.dat", header = None) # header = False since the data has no header.
    
    data_out = df_in.transpose()
    
    data_out.to_excel("example.xlsx", index = False, header = False) # index and header False since you don't want row or column indices written to the excel file.
    

    输出:

    a1  b1  c1
    a2  b2  c2
    a3  b3  c3
    a4  b4  c4
    

    优点:简单干净。 缺点:这个实现需要openpyxl

    安装为:pip install openpyxl

    【讨论】:

    • 对不起,我先看到了,看起来效率很高,但是pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader.read() pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_low_memory() pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._read_rows() pandas/_libs/parsers.pyx in pandas._libs.parsers.TextReader._tokenize_rows() pandas/_libs/parsers.pyx in pandas._libs.parsers.raise_parser_error() ParserError: Error tokenizing data. C error: Expected 104 fields in line 2, saw 105.
    • 给我看一段你的数据。
    • 真的很抱歉我不能给出数据,@NyxHolas 已经解决了,我认为这是同样的问题,因为我的数据行是锯齿状数组
    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多