簡體   English   中英

在 python 中讀取制表符分隔值 txt 文件時遇到問題

[英]having trouble reading tab separated value txt file in python

我正在嘗試讀取從 AWS 存儲中提取的 python 中的制表符分隔值 txt 文件。 (用 XXX 審查 AWS 的憑證)

import io
import pandas as pd
import boto3
import csv
from bioservices import UniProt
from sqlalchemy import create_engine
s3 = boto3.resource(
    service_name='s3',
    region_name='us-east-2',
    aws_access_key_id='XXX',
    aws_secret_access_key='XXX'
)

所以這只是為了連接到 AWS。 接下來,當我運行此代碼以讀取存儲在 AWS 中的制表符分隔的 txt 文件時

txt = s3.Bucket('compound-bioactivity-original-files').Object('helper-files/kinhub_human_kinase_list_30092021.txt').get()
txt_reader = csv.reader(txt, delimiter='\t')
for line in txt_reader:
    print(line)

我得到這個 output 這不是我想要的。 並且使用 dialect='excel-tab' 而不是 delimiter='\t' 給我同樣的 output

['ResponseMetadata']
['AcceptRanges']
['LastModified']
['ContentLength']
['ETag']
['VersionId']
['ContentType']
['Metadata']
['Body']

您的代碼有幾個問題。

首先, Object.get()不返回 Amazon S3 object 的內容 相反,根據Object.get()文檔,它返回:

{
    'Body': StreamingBody(),
    'AcceptRanges': 'string',
    'LastModified': datetime(2015, 1, 1),
    'ContentLength': 123,
    'ETag': 'string',
    'VersionId': 'string',
    'CacheControl': 'string',
    'ContentDisposition': 'string',
    ...
    'BucketKeyEnabled': True|False,
    'TagCount': 123,
}

您可以通過插入print(txt)作為調試行來看到這種情況。

如果您想訪問 object 的內容,您將使用Body元素。 要檢索流式主體的內容,您可以使用.read()

但是,這會以二進制字符串的形式返回,因為 object 被視為二進制文件。 在 Python 中,您可以使用.decode('ascii')將其轉換回 ASCII。 請參閱:如何在 Python3 中將“二進制字符串”轉換為普通字符串?

因此,您實際上需要使用:

txt = s3.Bucket('bucketname').Object('object.txt').get()['Body'].read().decode('ascii')

(如果這看起來太復雜,那么您可以簡單地將文件下載到本地磁盤,然后在文件上使用 CSV 閱讀器——它可以很好地工作而無需使用 get/read/decode。)

下一個問題是csv.reader的文檔說:

csv.reader(csvfile, dialect='excel', **fmtparams)
返回一個閱讀器 object,它將遍歷給定 csv 文件中的行。 csvfile可以是任何支持迭代器協議的object,每次調用next ()方法時返回一個字符串

由於decode()命令返回一個string ,因此for循環將遍歷 string 中的單個字符而不是string 中的行。

坦率地說,您可以在不使用 CSV 閱讀器的情況下處理這些行,只需拆分行和選項卡,如下所示:

import boto3

s3 = boto3.resource('s3')

txt = s3.Bucket('bucketname').Object('object.txt').get()['Body'].read().decode('ascii')

lines = txt.split('\n')

for line in lines:
    fields = line.split('\t')
    print(fields)

通過添加一些調試來查看每個步驟是否返回了您期望的數據,例如在每個步驟之后打印變量的內容,上述所有問題應該已經很明顯了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM