【问题标题】:Data Loss reading from one file, processing and writing to another? Python从一个文件读取、处理和写入另一个文件的数据丢失? Python
【发布时间】:2016-10-18 06:42:55
【问题描述】:

我编写了一个脚本,将一个包含 40k+ 行无序数据的 4MB 大文本文件转换为一个特定格式且更易于处理的 CSV 文件。

问题

分析我的文件大小,我似乎丢失了超过 1MB 的数据(20K 行 | edit: 原始文件是 7MB,因此丢失了 ~4MB 的数据),当我尝试搜索特定sorted_CSV.csvCommaOnly.txt 中存在的数据点我找不到它们。

我觉得这真的很奇怪。

我尝试了什么

我搜索并替换了 CommaOnly.txt 中可能导致问题的所有 unicode 字符。不走运!

示例: \u0b99 替换为 " "

这是一些数据丢失的示例

一行来自:CommaOnly.txt

name,SJ Photography,category,Professional Services,
state,none,city,none,country,none,about,
Capturing intimate & milestone moment from pregnancy and family portraits to weddings

Sorted_CSV.csv

Not present.

这可能是什么原因造成的?

代码:

import re
import csv
import time

# Final Sorted Order for all data:
#['name',   'data',
# 'category','data',
# 'about',  'data',
# 'country', 'data',
# 'state',   'data',
# 'city',   'data']


    ## Recieves String Item, Splits on "," Delimitter Returns the split List
def split_values(string):
    string = string.strip('\n')
    split_string = re.split(',', string)
    return split_string


    ## Iterates through the list, reorganizes terms in the desired order at the desired indices
    ## Adds the field if it does not initially 
def reformo_sort(list_to_sort):
    processed_values=[""]*12
    for i in range(11):
        try:
            ## Terrible code I know, but trying to be explicit for the question
            if(i==0):
                for j in range(len(list_to_sort)):
                    if(list_to_sort[j]=="name"):
                        processed_values[0]=(list_to_sort[j])
                        processed_values[1]=(list_to_sort[j+1])
                            ## append its neighbour

                ## if after iterating, name does not appear, add it.
                if(processed_values[0] != "name"):
                    processed_values[0]="name"
                    processed_values[1]="None"

            elif(i==2):
                for j in range(len(list_to_sort)):
                    if(list_to_sort[j]=="category"):
                    processed_values[2]=(list_to_sort[j])
                    processed_values[3]=(list_to_sort[j+1])

                if(processed_values[2] != "category"):
                    processed_values[2]="category"
                    processed_values[3]="None"

            elif(i==4):
                for j in range(len(list_to_sort)):
                    if(list_to_sort[j]=="about"):
                        processed_values[4]=(list_to_sort[j])
                        processed_values[5]=(list_to_sort[j+1])

                if(processed_values[4] != "about"):
                    processed_values[4]="about"
                    processed_values[5]="None"

            elif(i==6):
                for j in range(len(list_to_sort)):
                    if(list_to_sort[j]=="country"):
                        processed_values[6]=(list_to_sort[j])
                        processed_values[7]=(list_to_sort[j+1])
                if(processed_values[6]!= "country"):
                    processed_values[6]="country"
                    processed_values[7]="None"

            elif(i==8):
                for j in range(len(list_to_sort)):
                    if(list_to_sort[j]=="state"):
                        processed_values[8]=(list_to_sort[j])
                        processed_values[9]=(list_to_sort[j+1])

                if(processed_values[8] != "state"):
                    processed_values[8]="state"
                    processed_values[9]="None"

            elif(i==10):
                for j in range(len(list_to_sort)):
                    if(list_to_sort[j]=="city"):
                        processed_values[10]=(list_to_sort[j])
                        processed_values[11]=(list_to_sort[j+1])

                if(processed_values[10] != "city"):
                    processed_values[10]="city"
                    processed_values[11]="None"
        except:
            print("failed to append!")
    return processed_values

    # Converts desired data fields to a string delimitting values by ','
def to_CSV(values_to_convert):
    CSV_ENTRY=str(values_to_convert[1])+','+str(values_to_convert[3])+','+str(values_to_convert[5])+','+str(values_to_convert[7])+','+str(values_to_convert[9])+','+str(values_to_convert[11])
    return CSV_ENTRY


with open("CommaOnly.txt", 'r') as c:
    print("Starting.. :)")

    for line in c:
        entry = c.readline()
        to_sort = split_values(entry)
        now_sorted = reformo_sort(to_sort)
        CSV_ROW=to_CSV(now_sorted)
        with open("sorted_CSV.csv", "a+") as file:
            file.write(str(CSV_ROW)+"\n")

print("Finished! :)")
time.sleep(60)

【问题讨论】:

  • 您正在导入 csv 模块,但使用 re.split 读取行。不是很安全,取决于 csv 文件的内容。如果您在 Windows 上运行,请尝试在“rb”而不是“r”中打开 CommaOnly.txt。一个 \r 很容易漏掉而不被发现,然后对于你打开+关闭输出文件的每一行:你应该在启动时打开它
  • 您是否尝试过打印每个函数的返回值?您可以找出导致问题的功能。

标签: python file csv io


【解决方案1】:

我已经使用 csv 包重写了对我来说似乎很可疑的主循环。

您的reformo_sort 例程不完整且语法不正确,带有空的elif 块和缺少处理,所以我得到了不完整的行,但这应该比您的代码好得多。请注意 csv 的使用、“二进制”标志、以写入模式单独打开而不是打开/关闭每一行(快得多)以及 now_sorted 数组的 1-out-of-2 过滤。

with open("CommaOnly.txt", 'rb') as c:
    print("Starting.. :)")
    cr = csv.reader(c,delimiter=",",quotechar='"')
    with open("sorted_CSV.csv", "wb") as fw:
        cw = csv.writer(fw,delimiter=",",quotechar='"')

        for to_sort in cr:
            now_sorted = reformo_sort(to_sort)
            cw.writerow(now_sorted[1::2])

【讨论】:

  • 哇,飞得真快! rb 和 wb 参数必须分别更改为 'r' 和 'w' 才能使代码正常工作,但所有数据都完好无损!
  • 很高兴它对您有用,尽管不确定是什么导致了问题。您是偶然写入网络/NAS 驱动器的吗?
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 2012-12-04
  • 2018-10-30
  • 2012-10-22
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多