python代码仅从gcs存储桶中读取部分csv文件

时间:2019-12-15 19:36:59

标签: python google-cloud-storage google-cloud-composer

从Google云存储存储桶读取一个csv文件并将其写入同一存储桶中不同文件夹中的文件时,我遇到一个奇怪的问题。

我有一个名为test.csv的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')

enter image description here 但是当我尝试在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)

enter image description here

我还在存储桶中看到文件test.csv和cleansed_test.csv的大小相同。

我唯一能想到的是因为文件应该在gcs存储桶中压缩,所以我应该以其他方式打开文件。因为当我将文件下载到本地时,它们比存储桶中的文件大得多。

请告知。

谢谢。

2 个答案:

答案 0 :(得分:0)

我认为您可以通过使用dataframe列对象的replace方法并指定bool true参数(否则字段字符串必须完全匹配匹配字符的条件)来实现所需的目标。这样,您可以简单地对每一列进行迭代并替换不需要的字符串,然后用新修改的一列重写每一列。

我修改了一些代码,并在GCP中的VM上运行了它。如您所见,我更喜欢使用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

希望我的努力解决了您的问题...

答案 1 :(得分:0)

对于任何一个好奇的人来说,这就是如何为扩展名为.csv但实际上使用gzip压缩的文件进行膨胀。 gsutil猫gs://BUCKET/File_Name.csv | zcat | gsutil cp-gs://BUCKET/Newfile.csv

我在这里看到的唯一问题是 我不能使用通配符,或者应该说清楚一点,我们必须指定目标文件名

不利的一面是因为我必须指定目标文件名,所以我无法在气流中的bash运算符中使用它(这就是我想的我可能是错的)

谢谢

任何方式希望对您有帮助