В поисках идеального метода «очистки» CSV-файла для помещения в Excel - PullRequest
1 голос
/ 30 апреля 2020

Сложная настройка для этого вопроса, но потерпите меня!

(Копирование и вставка приведенного ниже блока в редактор работает хорошо)

Я использую clevercsv для загрузки своих данных из файла CSV финансового сайта. Каждая строка сохраняется как элемент в списке.

data = clevercsv.wrappers.read_csv(in_file_name)

После некоторых информационных строк учетной записи начинаются данные запаса:

stock_data = data[8:]

I sh для удаления данных: Рынок, Стоимость ссуды - вплоть до - Дневного максимума (включительно0

И символ сохранения, Описание ->% позиций (включительно), 52-недельного минимума , 52-нед. High

Каждая акция имеет соответствующие данные в соответствующей строке. Есть ли рекомендации по удалению этих данных? Я пытался, и, похоже, с ошибками logi c.

На дату, 2020-04-29 18: 44: 29

Счет, TD Direct Investing - HAHAHA

Ca sh, 123.12

Инвестиции, 1234.12

Общая стоимость, 12345.12

Маржа, 123456.12,

,

Символ, Рынок, Описание, Количество, Средняя стоимость, Цена, Стоимость книги, рыночная стоимость, нереализованные $, нереализованные%,% позиций, стоимость ссуды, изменение сегодня $, изменение сегодня%, ставки, лоты предложения, аск, лоты спроса, объем, минимум дня, максимум дня, минимум 52 недели, 52-недельный максимум

AFL, США, "AFLA C IN C", 500,43,79,39,23,21895,79,19615,00, -2280,79, -10,42,7,26, 1,4399986,3,81,39,19,40,2,1 , 3001288,38.31,39.48,23.07,57.18

AKTS, US, "AKOUSTIS TECHNOLOGIES IN C", 2500,5.04,8.94,12609.87,22350.00,9740.13,77.24,8,27, 0,35999966,40, 8.68,1,9.2,10,1161566,8.65,9.25,3.76,9.25

А вот мой код:

import clevercsv
data = clevercsv.wrappers.read_csv(in_file_name)

# store the earlier lines for later use, all rows 8 and later are stock data
cash = data[2]
investments = data[3]
tot_value = data[4]
margin = data[5]
full_header = data[7]
stock_data = data[8:]

new_header = []
new_stock_data = []

# I have found the index positions I wish to save, append their data to the new_ lists:
for i in range(len(full_header)):
    if i == 0:
        new_header.append(full_header[i])
    if (i >= 2 and i <= 10):
        new_header.append(full_header[i])
    if i == 21:
        new_header.append(full_header[i])
    if i == 22: 
        new_header.append(full_header[i])
# I have found the index positions I wish to save, append their data to the new_ lists:
for i in range(len(stock_data)):
    if i == 0:
        new_stock_data.append(stock_data[i])
    if (i >= 2 and i <= 10):
        new_stock_data.append(stock_data[i])
    if i == 21:
        new_stock_data.append(stock_data[i])
    if i == 22: 
        new_stock_data.append(stock_data[i])

with open(os.path.join(folder_path,out_file_name),'w') as out_file:
    writer = clevercsv.writer(out_file)
    writer.writerow(cash)
    writer.writerow(investments)
    writer.writerow(tot_value)
    writer.writerow(margin)
    writer.writerow(new_header)
    for row in new_stock_data:
         writer.writerow(row)

Если это слишком сложно, я понимаю и если у кого-то есть лучшая библиотека для использования или лучший способ использовать библиотеку csv, то это поможет вам самим.

Ответы [ 3 ]

1 голос
/ 30 апреля 2020

В Python я бы рекомендовал использовать Pandas для операций такого типа.

Сначала изолируйте данные CSV. Тогда относитесь к нему как к ручью. Я отбрасываю часть вашего образца как x:

# This is python3 code
# first treat string as though it is a file
import io
x = io.StringIO("""Symbol,Market,Description,Quantity,Average Cost,Price,Book Cost,Market Value,Unrealized $,Unrealized %,% of Positions,Loan Value,Change Today $,Change Today %,Bid,Bid Lots,Ask,Ask Lots,Volume,Day Low,Day High,52-wk Low,52-wk High
AFL,US,"AFLAC INC",500,43.79,39.23,21895.79,19615.00,-2280.79,-10.42,7.26,,1.4399986,3.81,39.19,1,40.2,1,3001288,38.31,39.48,23.07,57.18
AKTS,US,"AKOUSTIS TECHNOLOGIES INC",2500,5.04,8.94,12609.87,22350.00,9740.13,77.24,8.27,,0.35999966,4.20,8.68,1,9.2,10,1161566,8.65,9.25,3.76,9.25""")

Затем используйте pandas, чтобы прочитать строку как CSV, обрабатывая первую строку как заголовки по умолчанию:

import pandas as pd
df = pd.read_csv(x)

Затем выберите нужные столбцы, передав список имен столбцов во фрейм данных:

new_df = df[['Book Cost', 'Market Value', 'Unrealized $', 'Unrealized %','% of Positions','52-wk Low', '52-wk High']]
   Book Cost  Market Value  Unrealized $  Unrealized %  % of Positions  \
0   21895.79       19615.0      -2280.79        -10.42            7.26   
1   12609.87       22350.0       9740.13         77.24            8.27   

   52-wk Low  52-wk High  
0      23.07       57.18  
1       3.76        9.25 

Наконец, вы можете сохранить его:

new_df.to_csv('test.csv', index=False)  # Turn off indexing

И вы набор:

Book Cost,Market Value,Unrealized $,Unrealized %,% of Positions,52-wk Low,52-wk High
21895.79,19615.0,-2280.79,-10.42,7.26,23.07,57.18
12609.87,22350.0,9740.13,77.24,8.27,3.76,9.25
1 голос
/ 30 апреля 2020

(Полное раскрытие, я автор CleverCSV.)

Если вы хотите использовать CleverCSV для этой задачи, и ваши данные достаточно малы, чтобы поместиться в память, вы можете использовать clevercsv.read_csv для загрузки данных и clevercsv.write_table для сохранения данных. Используя эти функции, вам не нужно беспокоиться о диалектах CSV и т. Д. c. Вы также можете найти индекс строки заголовка автоматически. Это может go что-то вроде этого:

from clevercsv import read_csv, write_table

# Load the table with CleverCSV
table = read_csv(in_file_name)

# Find the index of the header row and get the header
header_idx = next((i for i, r in enumerate(table) if r[0] == 'Symbol'), None)
header = table[header_idx]

# Extract the data as a separate table
data = table[header_idx+1:]

# Create a list of header names that you want to keep
keep = ["Symbol", "Description", "Quantity","Average Cost","Price","Book Cost","Market Value","Unrealized $","Unrealized %","% of Positions","52-wk Low", "52-wk High"]

# Turn that list into column indices (and ensure all exist)
keep_idx = [header.index(k) for k in keep]

# Then create a new table by adding the header and the sliced rows
new_table = [keep]
for row in data:
  new_row = [row[i] for i in keep_idx]
  new_table.append(new_row)

# Finally, write the table to a new csv file
write_table(new_table, out_file_name)
1 голос
/ 30 апреля 2020

Если вы уже знаете индексы столбцов и длину заголовка, вы можете сделать что-то вроде этого:

import csv

with open('input.csv', 'r', newline='') as input_file, open('output.csv','w', newline='') as output_file:
    reader = csv.reader(input_file)
    writer = csv.writer(output_file)

    for line_number, row in enumerate(reader, start=0):  # Avoid range(len(x))
        if line_number < 7:
            writer.writerow(row)  # Write cash, investments, etc
        else:
            shortened_row = row[0:1] + row[2:11] + row[21:] # Slice only the columns you need
            writer.writerow(shortened_row)

Всякий раз, когда вы пишете range(len(something)), это хороший признак того, что вы, вероятно, захотите использовать enumerate(), который будет l oop просматривать ваши данные и автоматически отслеживать текущий индекс.

Для анализа каждой строки после заголовка вы можете использовать нотацию срезов row[start:end] и добавлять фрагменты вместе в получить новый список, который вы можете записать в файл. Имейте в виду, что row[start:end] будет не возвращать элемент с индексом end, что может быть нелогичным.

Наконец, я всегда добавляю newline='' при работе с CSV, так как в противном случае вы можете получить неожиданные разрывы строк, но это может быть то, что clevercsv обрабатывает для вас.

...