AWS S3 पर एक पाठ फ़ाइल को डिस्क में लिखे बिना पांडा में कैसे आयात करें


98

मेरे पास S3 पर एक टेक्स्ट फ़ाइल बची है जो एक टैब सीमांकित तालिका है। मैं इसे पांडा में लोड करना चाहता हूं, लेकिन इसे पहले नहीं बचा सकता क्योंकि मैं एक हरको सर्वर पर चल रहा हूं। यह है, जो कि अभी तक मेरे पास है।

import io
import boto3
import os
import pandas as pd

os.environ["AWS_ACCESS_KEY_ID"] = "xxxxxxxx"
os.environ["AWS_SECRET_ACCESS_KEY"] = "xxxxxxxx"

s3_client = boto3.client('s3')
response = s3_client.get_object(Bucket="my_bucket",Key="filename.txt")
file = response["Body"]


pd.read_csv(file, header=14, delimiter="\t", low_memory=False)

त्रुटि है

OSError: Expected file path name or file-like object, got <class 'bytes'> type

मैं प्रतिक्रिया निकाय को एक प्रारूप में कैसे परिवर्तित करूँगा जो पांडा स्वीकार करेंगे?

pd.read_csv(io.StringIO(file), header=14, delimiter="\t", low_memory=False)

returns

TypeError: initial_value must be str or None, not StreamingBody

pd.read_csv(io.BytesIO(file), header=14, delimiter="\t", low_memory=False)

returns

TypeError: 'StreamingBody' does not support the buffer interface

अद्यतन - निम्नलिखित कार्य का उपयोग करना

file = response["Body"].read()

तथा

pd.read_csv(io.BytesIO(file), header=14, delimiter="\t", low_memory=False)

इसे इस तरह का प्रयास करें: io.BytesIO(file)या io.StringIO(file)के बजाय fileमें read_csv()कॉल
MaxU

आप इस उत्तरio.StringIO में उपयोग कर सकते हैं ।
इयन्स

इन सुझावों में से किसी ने भी काम नहीं किया। आप मेरे पोस्ट एडिट में त्रुटियों को देख सकते हैं।
आलपालपाल

1
अद्यतन हिस्सा मेरे लिए काम किया। धन्यवाद।
विम बर्चमांस

जवाबों:


116

pandasके लिए उपयोग करता botoहै read_csv, तो आप करने में सक्षम होना चाहिए:

import boto
data = pd.read_csv('s3://bucket....csv')

यदि आप की जरूरत है boto3क्योंकि आप पर हैं python3.4+, तो आप कर सकते हैं

import boto3
import io
s3 = boto3.client('s3')
obj = s3.get_object(Bucket='bucket', Key='key')
df = pd.read_csv(io.BytesIO(obj['Body'].read()))

चूंकि संस्करण 0.20.1 pandas उपयोग करता है s3fs, नीचे उत्तर देखें।


क्या किसी URL को सभी के लिए सार्वजनिक किए बिना उपयोग करने का कोई तरीका है? फ़ाइल को निजी रहने की आवश्यकता है।
अल्‍पालपाल

boto3: डॉक्स को कॉन्फ़िगर प्रमाणीकरण करने के लिए इतना है कि आप निजी फ़ाइलें साथ ही उपयोग कर सकते हैं दिखाने के boto3.readthedocs.io/en/latest/guide/quickstart.html
स्टीफन

1
यह NoCredentialsError फेंक रहा है। मैं s3 क्रेडेंशियल्स को कैसे सेट करूं? मैं अजगर और बोटो के लिए नया हूं
सुनील राव

15
मैंने पाया कि मुझे अंतिम उदाहरण boto3 के साथ करना था: df = pd.read_csv(io.BytesIO(obj['Body'].read()), encoding='utf8')
user394430

यह उत्तर पुराना है । कृपया वेसम का उत्तर देखें ।
जेरिट

85

अब पांडा S3 URL को संभाल सकते हैं । आप बस कर सकते हैं:

import pandas as pd
import s3fs

df = pd.read_csv('s3://bucket-name/file.csv')

s3fsयदि आपके पास नहीं है तो आपको इंस्टॉल करने की आवश्यकता हैpip install s3fs

प्रमाणीकरण

यदि आपकी S3 बाल्टी निजी है और प्रमाणीकरण की आवश्यकता है, तो आपके पास दो विकल्प हैं:

1- अपनी कॉन्फ़िग फ़ाइल में एक्सेस क्रेडेंशियल जोड़ें~/.aws/credentials

[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

या

2- निम्नलिखित पर्यावरण चर को उनके उचित मूल्यों के साथ सेट करें :

  • aws_access_key_id
  • aws_secret_access_key
  • aws_session_token

सुंदर। Python3 में काम करता है।
काइलर ब्राउन

प्रमाणीकरण के बारे में कैसे ..?
जेम्स विर्ज़बा

1
@JamesWierzba, मैंने अपने उत्तर के ऊपर प्रमाणीकरण पर अधिक विवरण जोड़ा है।
वेसम

3
जब कई एवर्स प्रोफाइल के साथ काम करते हैं, तो आप कैसे चुन सकते हैं कि किस प्रोफाइल का उपयोग किया जाना चाहिए? s3fs में profile_name विकल्प है, लेकिन मुझे यकीन नहीं है कि यह पांडा के साथ कैसे काम करता है।
इवो ​​मर्चियर्स

1
@ इन्स वास्तव में नहीं, वर्तमान में, मैं पहली बार फ़ाइल ऑब्जेक्ट को s3fs (निर्दिष्ट प्रोफ़ाइल का उपयोग करके) के साथ खोलता हूं और फिर मैं इसे पांडा के साथ पढ़ता हूं, जैसे वे यहां करते हैं github.com/pandas-dev/pandas/issues/16692
Ivo मर्चियर्स

16

यह अब नवीनतम पांडा में समर्थित है। देख

http://pandas.pydata.org/pandas-docs/stable/io.html#reading-remote-files

जैसे।,

df = pd.read_csv('s3://pandas-test/tips.csv')

4
याद रखें 'S3 URL को संभाला जाता है, लेकिन S3Fs लाइब्रेरी को स्थापित करने की आवश्यकता होती है'
जूलियो विलेन

प्रामाणिकता के बारे में क्या है
जेम्स व्येरबा

जब तक url कठिन न हो, जब तक कि url को सार्वजनिक रूप से उजागर नहीं किया जाता है, यह सुनिश्चित नहीं होता है कि क्या सरल / आधारभूत http सामान्य काम करेगा,
Raveen Beemsingh

10

S3fs के साथ इसे निम्नानुसार किया जा सकता है:

import s3fs
import pandas as pd
fs = s3fs.S3FileSystem(anon=False)

# CSV
with fs.open('mybucket/path/to/object/foo.pkl') as f:
    df = pd.read_csv(f)

# Pickle
with fs.open('mybucket/path/to/object/foo.pkl') as f:
    df = pd.read_pickle(f)

2
मुझे लगता है कि s3fs के साथ आप लिख भी सकते हैंdf = pd.read_csv('s3://mybucket/path/to/object/foo.pkl')
louis_guitton

1
@louis_guitton यह pd-read_csv के साथ काम करने लगता है, लेकिन read_pickle के साथ नहीं
Sip

2

चूंकि फाइलें बहुत बड़ी हो सकती हैं, इसलिए उन्हें पूरी तरह से डेटाफ्रेम में लोड करना बुद्धिमानी नहीं है। इसलिए, लाइन को लाइन से पढ़ें और डेटाफ्रेम में सहेजें। हां, हम read_csv में रंक आकार भी प्रदान कर सकते हैं, लेकिन फिर हमें पढ़ी गई पंक्तियों की संख्या को बनाए रखना होगा।

इसलिए, मैं इस इंजीनियरिंग के साथ आया:

def create_file_object_for_streaming(self):
        print("creating file object for streaming")
        self.file_object = self.bucket.Object(key=self.package_s3_key)
        print("File object is: " + str(self.file_object))
        print("Object file created.")
        return self.file_object

for row in codecs.getreader(self.encoding)(self.response[u'Body']).readlines():
            row_string = StringIO(row)
            df = pd.read_csv(row_string, sep=",")

एक बार काम पूरा होने के बाद मैं df को हटा भी देता हूं। del df


1

पाठ फ़ाइलों के लिए, आप उदाहरण के लिए पाइप-सीमांकित फ़ाइल के साथ नीचे दिए गए कोड का उपयोग कर सकते हैं: -

import pandas as pd
import io
import boto3
s3_client = boto3.client('s3', use_ssl=False)
bucket = #
prefix = #
obj = s3_client.get_object(Bucket=bucket, Key=prefix+ filename)
df = pd.read_fwf((io.BytesIO(obj['Body'].read())) , encoding= 'unicode_escape', delimiter='|', error_bad_lines=False,header=None, dtype=str)

0

एक विकल्प csv को json के माध्यम से रूपांतरित करना है df.to_dict()और फिर इसे स्ट्रिंग के रूप में संग्रहीत करना है। ध्यान दें कि यह केवल तभी प्रासंगिक है जब CSV एक आवश्यकता नहीं है, लेकिन आप बस जल्दी से डेटाफ़्रेम को S3 बाल्टी में डालना चाहते हैं और इसे फिर से प्राप्त करना चाहते हैं।

from boto.s3.connection import S3Connection
import pandas as pd
import yaml

conn = S3Connection()
mybucket = conn.get_bucket('mybucketName')
myKey = mybucket.get_key("myKeyName")

myKey.set_contents_from_string(str(df.to_dict()))

यह डीएफ को एक तानाशाह स्ट्रिंग में बदल देगा, और फिर इसे S3 में जसन के रूप में बचाएगा। आप इसे बाद में उसी जॅसन फॉर्मेट में पढ़ सकते हैं:

df = pd.DataFrame(yaml.load(myKey.get_contents_as_string()))

अन्य समाधान भी अच्छे हैं, लेकिन यह थोड़ा सरल है। यमल जरूरी नहीं हो सकता है लेकिन आपको जस स्ट्रिंग को पार्स करने के लिए कुछ चाहिए। S3 फ़ाइल जरूरी नहीं है, तो जरूरत है एक सीएसवी होने के लिए इस त्वरित सुधार हो सकता है।


0

अजगर 3.6+ के लिए अमेज़ॅन के पास अब अपनी सेवाओं के साथ पंडों का उपयोग करने के लिए एक बहुत अच्छा पुस्तकालय है, जिसे वेस्वरंगलर कहा जाता है ।

import awswrangler as wr
import boto3


# Boto3 session
session = boto3.session.Session(aws_access_key_id='XXXX', 
                                aws_secret_access_key='XXXX')

# Awswrangler pass forward all pd.read_csv() function args
df = wr.s3.read_csv(path='s3://bucket/path/',
                    boto3_session=session,
                    skiprows=2,
                    sep=';',
                    decimal=',',
                    na_values=['--'])

आव्रजन स्थापित करने के लिए: pip install awswrangler


-1
import s3fs
import pandas as pd
s3 = s3fs.S3FileSystem(profile='<profile_name>')
pd.read_csv(s3.open(<s3_path>))

1
कृपया अपने कोड में कुछ स्पष्टीकरण जोड़ें।
andrey.shedko
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.