код Python читает только частичный CSV-файл из ведра gcs

Я столкнулся со странной проблемой при чтении файла csv из корзины облачного хранилища Google и записи его в файл в другой папке в той же корзине.

У меня есть файл csv с именем test.csv со 1000001 строкой. Я пытаюсь заменить "в каждой строке пустым пространством и записать в файл с именем cleansed_test.csv.

Я протестировал свой код локально и работает, как ожидалось.

ниже приведен код, который я использую в своем локальном

import pandas as pd
import csv
import re
new_lines=[]
new_lines_error_less_cols=[]
new_lines_error_more_cols=[]
with open('c:\\Users\test_file.csv','r') as f:
    lines = f.readlines()
    print(len(lines))
    for line in lines:
        new_line = re.sub('["]','',line)
        new_line= new_line.strip()
        new_lines.append(new_line)
#         elif line.count('|') < 295:
#             new_line_error_less = re.sub('["]','inches',line)
#             new_line_error_less= new_line_error_less.strip()
#             new_lines_error_less_cols.append(new_line_error_less)
#         else:
#             new_line_error_more = re.sub('["]','inches',line)
#             new_line_error_more= new_line_error_more.strip()
#             new_lines_error_more_cols.append(new_line_error_more)
    new_data = pd.DataFrame(new_lines)
    print(new_data.info())
    #new_data.to_csv('c:\\cleansed_file.csv',header=None,index=False,encoding='utf-8')

введите здесь описание изображения Но когда я пытаюсь сделать тот же файл в ведре gcs, читается только 67514 строк, код, который я использую в композиторе

def replace_quotes(project,bucket,**context):
        import pandas as pd
        import numpy as np
        import csv
        import os
        import re
        import gcsfs
        import io
        fs = gcsfs.GCSFileSystem(project='project_name')
        updated_file_list = fs.ls('bucketname/FULL')
        updated_file_list = [ x for x in updated_file_list if "filename" in x ]
        new_lines=[]
        new_lines_error_less_cols=[]
        new_lines_error_more_cols=[]
        for f in updated_file_list:
            file_name = os.path.splitext(f)[0]
            parse_names = file_name.split('/')
            filename = parse_names[2]
            bucketname  = parse_names[0]
            with fs.open("gs://"+f,'r') as pf:
                lines = pf.readlines()
                print("length of lines----->",len(lines))#even here showing 67514
                for line in lines:
                    new_line = re.sub('["]','',line)
                    new_line= new_line.strip()
                    new_lines.append(new_line)
            new_data = pd.DataFrame(new_lines)
            #new_data.to_csv("gs://"+bucketname+"/ERROR_FILES/cleansed_"+filename+".csv",escapechar='',header = None,index=False,encoding='utf-8',quoting=csv.QUOTE_NONE)

введите описание изображения здесь

Также в корзине я вижу, что размеры файлов test.csv и cleansed_test.csv одинаковы.

Единственное, о чем я могу думать, это то, что файлы сжимаются в ведрах gcs, если я открываю файлы другим способом. Потому что, когда я загружаю файлы на локальный компьютер, они намного больше, чем то, что я вижу в корзине.

Пожалуйста, порекомендуйте.

Спасибо.


person kumarm    schedule 15.12.2019    source источник
comment
Трудно понять, что происходит, когда вы сравниваете local и gcs с очень разным кодом.   -  person barny    schedule 15.12.2019
comment
Вы пробовали сделать так, чтобы ваш код читался из gcs и записывался в локальный файл? Вы пробовали сравнить, что происходит с файлом гораздо меньшего размера (например, 100 строк?)? Есть ли в ваших CSV-файлах значения, включающие cr / lf? Есть ли в вашем файле значения, которые включают "", потому что это будет означать, что значение окружено ", что полностью нарушит ваш код, обрабатывающий файл csv как текст. Вам следует отредактировать в своем вопросе минимальный минимальный воспроизводимый пример   -  person barny    schedule 15.12.2019
comment
Привет, извините за поздний ответ. Прежде чем продолжить эту беседу, я хотел бы снова сделать свое дело. @barny, эй, хотя коды выглядят немного иначе, потому что один находится в моем локальном, другой - в ведре gcp, но логика точно такая же.   -  person kumarm    schedule 18.12.2019
comment
Кроме того, я не могу воспроизвести эту проблему, так как я могу успешно запускать все на своем локальном компьютере. Но вот мои наблюдения. Мы получаем csv-файл в нашу корзину от sap dataservices, файл сжимается внутри корзины, но расширение файла - .csv, а не gz, а размер сжатого файла - 59 МБ (фактический размер - 900 МБ). и когда я пытаюсь создать еще один CSV из этого файла, все работает, но когда новый файл достигает размера 59 МБ, это происходит, когда запись данных в файл останавливается.   -  person kumarm    schedule 18.12.2019
comment
Итак, в основном мой вопрос заключается в том, как я могу прочитать весь файл (также сжатие, используемое на стороне dataservices, - это gzip), но расширение сжатого файла в ведре - .csv, поэтому я не уверен, как я могу этого добиться.   -  person kumarm    schedule 18.12.2019


Ответы (2)


Я думаю, что вы можете добиться того, чего хотите, используя метод replace объекта столбца фрейма данных и указав параметр bool true (в противном случае строка поля должна полностью соответствовать условию соответствия символа). Таким образом, вы можете просто выполнить итерацию для каждого столбца и заменить ненужную строку, после чего переписать каждый столбец новым измененным.

Я немного изменил ваш код и запустил его на своей виртуальной машине в GCP. Как видите, я предпочел использовать метод Pandas.read_csv (), поскольку метод GCSF выдавал мне несколько ошибок. Кажется, что код выполняет свою работу, поскольку я изначально тестировал замену фиктивной общей строки, и он работал плавно.

Это ваш измененный код. Также обратите внимание, что я немного реорганизовал часть чтения, поскольку она не соответствовала пути csv в моем ведре.

from pandas.api.types import is_string_dtype
import pandas as pd
import numpy as np
import csv
import os
import re
import gcsfs
import io
fs = gcsfs.GCSFileSystem(project='my-project')
updated_file_list = fs.ls('test-bucket/')
updated_file_list = [ x for x in updated_file_list if "simple.csv" in x ]
new_lines=[]
new_lines_error_less_cols=[]
new_lines_error_more_cols=[]


for f in updated_file_list:
        file_name = os.path.splitext(f)[0]
        print(f, file_name)
        parse_names = file_name.split('/')
        filename = parse_names[1]
        bucketname  = parse_names[0]
        with fs.open("gs://"+f) as pf:
            df = pd.read_csv(pf)
            #print(df.head(len(df)))  #To check results
            for col in df:
                if is_string_dtype(df[col]):
                    df[col] = df[col].replace(to_replace=['"'], value= '', regex= True)
            #print(df.head(len(df))) #To check results

        new_data = pd.DataFrame(df)
        #new_data.to_csv("gs://"+bucketname+"/ERROR_FILES/cleansed_"+filename+".csv",escapechar='',header = None,index=False,encoding='utf-8',quoting=csv.QUOTE_NONE

Надеюсь, мои усилия решили вашу проблему ...

person Federico Taranto    schedule 19.12.2019
comment
Привет, Федерико, спасибо за ваш вклад, но моя проблема в том, что я должен надуть файл csv, а затем прочитать его, но поскольку мой сжатый файл имеет расширение (.csv), а не .gz, я не уверен, как его сдуть. Логически мой код работает, он просто читает и записывает только до тех пор, пока не будет достигнут размер файла (скопированный), а затем остановится. - person kumarm; 02.01.2020

для всех, кому интересно, вот как раздуть файл с расширением .csv, но на самом деле сжатый с помощью gzip. gsutil cat gs: //BUCKET/File_Name.csv | zcat | gsutil cp - gs: //BUCKET/Newfile.csv

Единственная проблема здесь, которую я вижу, это то, что я не могу использовать подстановочные знаки, или, проще говоря, мы должны указать имя файла назначения.

нижняя сторона заключается в том, что мне нужно указать имя файла назначения, я не могу использовать его в операторе bash в воздушном потоке (это то, что я думаю, я могу ошибаться)

Благодарность

любыми способами надеюсь, что это поможет

person kumarm    schedule 23.01.2020