首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python中读取选项卡分隔值txt文件时有问题

在python中读取选项卡分隔值txt文件时有问题
EN

Stack Overflow用户
提问于 2022-01-04 02:09:08
回答 1查看 70关注 0票数 0

我试图在python中读取一个选项卡分隔的值txt文件,该文件是从AWS存储中提取的。(XXX为AWS审查的证书)

代码语言:javascript
复制
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文件时

代码语言:javascript
复制
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)

我得到了这个输出,这不是我想要的。使用方言=‘excel-tab’代替分隔符=‘\t’也给出了相同的输出。

代码语言:javascript
复制
['ResponseMetadata']
['AcceptRanges']
['LastModified']
['ContentLength']
['ETag']
['VersionId']
['ContentType']
['Metadata']
['Body']
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-04 05:17:34

您的代码有几个问题。

首先,Object.get()不返回S3对象的内容。相反,按照Object.get() documentation,它返回:

代码语言:javascript
复制
{
    '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)作为调试行来看到这种情况。

如果要访问对象的内容,可以使用Body元素。要检索流体的内容,可以使用.read()

但是,这将返回为二进制字符串,因为该对象被视为二进制文件。在Python中,可以使用.decode('ascii')将其转换回ASCII。请参阅:How to convert 'binary string' to normal string in Python3?

因此,您实际上需要使用:

代码语言:javascript
复制
txt = s3.Bucket('bucketname').Object('object.txt').get()['Body'].read().decode('ascii')

(如果这看起来太复杂了,那么您可以简单地将文件下载到本地磁盘,然后在文件上使用CSV -不用使用get/read/decode就可以很好地工作。)

下一个问题是,documentation for csv.reader说:

csv.reader(csvfile, dialect='excel', **fmtparams)

返回一个读取器对象,它将遍历给定csvfile中的行。csvfile可以是任何支持迭代器协议的对象,每次调用其next()方法时都返回一个字符串。

因为decode()命令返回一个字符串,所以for循环将迭代字符串中的单个字符,而不是字符串中的行。

坦率地说,您可以在不使用CSV的情况下处理行,只需在行和选项卡上拆分,如下所示:

代码语言:javascript
复制
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)

通过添加一些调试来查看每个步骤是否返回了您预期的数据,例如在每个步骤之后打印变量的内容,上述所有问题都应该是显而易见的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70573383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档