Python - чтение строк файла данных, перезапись в столбцы в Excel. CSV / NumPy / openpyxl - PullRequest
1 голос
/ 27 марта 2020

Я сталкиваюсь с некоторой проблемой с использованием 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, так что простите мою грязную структуру кода, что касается грамматики, я пытаюсь писать как можно точнее, а не сокращать код.

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Допустим, у нас есть файл example.dat со следующим:

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

Это лучше сделать с pandas. Сначала загрузите данные как фрейм данных , затем возьмите транспонирование и сохраните полученный фрейм данных в 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

1 голос
/ 27 марта 2020

Похоже, у вас есть некоторые проблемы с 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')
...