AWS Lambda - 读取csv文件并转换为pandas数据框架

7

我有一段简单的Lambda代码来读取S3存储桶中的CSV文件。一切运行良好,但是当我尝试将CSV数据转换为pandas数据帧时,会出现错误 string indices must be integers

我的代码很标准,但我需要将CSV作为数据帧用于进一步处理。下划线处是错误的源头。我可以顺利地打印数据,因此Bucket和文件细节已正确配置。

更新的代码:

import json
import pandas as pd
import numpy as np
import requests
import glob
import time
import os
from datetime import datetime
from csv import reader
import boto3
import traceback
import io

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    try:
            
        bucket_name = event["Records"][0]["s3"]["bucket"]["name"]
        s3_file_name = event["Records"][0]["s3"]["object"]["key"]
        resp = s3_client.get_object(Bucket=bucket_name, Key=s3_file_name)
        
        data = resp['Body'].read().decode('utf-8')
        df=pd.DataFrame( list(reader(data)))
        print (df.head())

    except Exception as err:
        print(err)
        

        
        
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello fr2om Lambda!')
    }
    
    traceback.print_exc()

请包含回溯消息,以便我们可以轻松地找到错误行。 - tdelaney
2
你尝试过 pd.read_csv(data) 吗? - ig0774
1
当你像 event["Records"][0]["s3"]["bucket"]["name"] 这样的代码出现问题时,你可以添加一些临时代码来缩小问题范围。首先试试 event["Records"] ,然后是 event["Records"][0]["s3"]event["Records"][0]["s3"]["bucket"],哪个报错就能知道问题所在了。 - tdelaney
@tdelaney。刚刚添加了更新的代码。当我运行它时,它给出了以下结果:响应: (..)-简短地切断 函数日志: 开始RequestId:d99891e1-6c63-4307-acb5-f94bcb92217c版本:$LATEST 0 0 ResponseMetadata 1 AcceptRanges 2 LastModified 3 ContentLength 4 ETag 结束RequestId:d99891e1-6c63-4307-acb5-f94bcb92217c 报告RequestId:d99891e1-6c63-4307-acb5-f94bcb92217c持续时间:463.01毫秒计费持续时间:500毫秒内存大小:128 MB最大内存使用量:128 MB初始化持续时间:1382.89毫秒 - Kalenji
1
你说代码现在可以工作,但是它不起作用?具体问题是什么,期望的结果是什么,请您澄清一下? - cs95
显示剩余2条评论
3个回答

10

我认为你的问题很可能与这行代码有关 - df=pd.DataFrame( list(reader(data))),请参考下面的答案,它可以让你将csv文件读入pandas数据框以进行处理。

import boto3
import pandas as pd
from io import BytesIO

s3_client = boto3.client('s3')

def lambda_handler(event, context):
   try:
       bucket_name = event["Records"][0]["s3"]["bucket"]["name"]
       s3_file_name = event["Records"][0]["s3"]["object"]["key"]
       resp = s3_client.get_object(Bucket=bucket_name, Key=s3_file_name)

       ###########################################
       # one of these methods should work for you. 
       # Method 1
       # df_s3_data = pd.read_csv(resp['Body'], sep=',')
       #
       # Method 2
       # df_s3_data = pd.read_csv(BytesIO(resp['Body'].read().decode('utf-8')))
       ###########################################
       print(df_s3_data.head())

   except Exception as err:
      print(err)

不行。它给了我“没有要从文件中解析的列”。 - Kalenji
@Kalenji 你试过被注释掉的第二个 df_s3_data 吗? - Life is complex
方法一可行!还有一个问题,你是否成功地按照文件名的一部分从S3获取文件到Lambda中? - Kalenji

3
import json
import pandas as pd
import numpy as np
import requests
import glob
import time
import os
from datetime import datetime
from csv import reader
import boto3
import io

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    try:
            
        bucket_name = event["Records"][0]["s3"]["bucket"]["name"]
        s3_file_name = event["Records"][0]["s3"]["object"]["key"]
        obj = s3_client.get_object(Bucket=bucket_name, Key= s3_file_name)
        df = pd.read_csv(obj['Body']) # 'Body' is a key word
        print(df.head())

    except Exception as err:
        print(err)
        
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello fr2om Lambda!')
    }

这个答案对我有用。在被接受的答案中执行的额外的.read()方法给我带来了错误。 - Некто

1

您可以直接使用read_csv从pandas读取S3文件:

s3_client = boto3.client('s3')

def lambda_handler(event, context):
    try:            
        bucket_name = event["Records"][0]["s3"]["bucket"]["name"]
        s3_file_name = event["Records"][0]["s3"]["object"]["key"]

        # This 'magic' needs s3fs (https://pypi.org/project/s3fs/)
        df=pd.read_csv(f's3://{bucket_name}/{s3_file_name}', sep=',')

        print (df.head())

    except Exception as err:
        print(err)

需要记住的事情:

   # Track memory usage at cost of CPU. Great for troubleshooting. Use wisely.
   print(df.info(verbose=True, memory_usage='deep'))  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接