পান্ডায় বৃহত্তর, অবিরাম ডেটা ফ্রেম


94

আমি দীর্ঘ সময়ের এসএএস ব্যবহারকারী হিসাবে পাইথন এবং পান্ডাসে স্যুইচিংয়ের সন্ধান করছি।

যাইহোক, আজ কিছু পরীক্ষা চালানোর সময়, আমি অবাক হয়ে গিয়েছিলাম যে pandas.read_csv()128 এমবি সিএসভি ফাইলে চেষ্টা করার সময় অজগরটি স্মৃতি থেকে সরে গেছে । এটিতে প্রায় 200,000 সারি এবং বেশিরভাগ সংখ্যা সংক্রান্ত ডেটা 200 কলাম ছিল।

এসএএসের সাহায্যে আমি একটি এসএএস ডেটাসেটে একটি সিএসভি ফাইল আমদানি করতে পারি এবং এটি আমার হার্ড ড্রাইভের চেয়েও বড় হতে পারে।

এর সাথে কিছু মিল আছে কি pandas?

আমি নিয়মিত বড় ফাইলগুলির সাথে কাজ করি এবং বিতরণকৃত কম্পিউটিং নেটওয়ার্কে অ্যাক্সেস নেই।


আমি পান্ডার সাথে পরিচিত নই, তবে আপনি ফাইলটির মাধ্যমে পুনরাবৃত্তি করতে চান। pandas.pydata.org/pandas-docs/stable/…
monkut

উত্তর:


81

নীতিগতভাবে এটি স্মৃতিশক্তি শেষ না হওয়া উচিত, তবে read_csvপাইথনের কিছু জটিল অভ্যন্তরীণ সমস্যার কারণে বড় ফাইলগুলিতে মেমরির সমস্যা রয়েছে (এটি অস্পষ্ট তবে এটি দীর্ঘদিন ধরেই পরিচিত: http://github.com/pydata / পান্ডাস / সংখ্যা / 407 )।

এই মুহুর্তে একটি নিখুঁত সমাধান নেই (এখানে একটি ক্লান্তিকর সমাধান: আপনি সারি-সারি ফাইলটি প্রাক-বরাদ্দ করা NumPy অ্যারে বা মেমরি-ম্যাপযুক্ত ফাইলের মধ্যে প্রতিলিপি করতে পারেন np.mmap), তবে এটির একটি আমি কাজ করব অদূর ভবিষ্যতে চালু। আরেকটি সমাধান হ'ল ফাইলটি ছোট ছোট টুকরো (ব্যবহার iterator=True, chunksize=1000) এর মধ্যে পড়া এবং তারপরে কনকনেট করা pd.concat। সমস্যাটি তখন উপস্থিত হয় যখন আপনি একটি বড় স্লুপে পুরো পাঠ্য ফাইলটিকে মেমরির মধ্যে টানুন।


4
বলুন আমি ফাইলটি পড়তে পারি এবং তাদের সমস্তকে একসাথে একটি ডেটাফ্রেমে রূপান্তর করতে পারি। ডেটাফ্রেমের কি স্মৃতিতে থাকতে হবে? এসএএস-এর সাহায্যে, হার্ড-ড্রাইভের জায়গা থাকা অবস্থায় আমি যে কোনও আকারের ডেটাসেটের সাথে কাজ করতে পারি। এটি কি ডেটাফ্রেমগুলির সাথে একই? আমি এই ধারণাটি পেয়েছি যে তারা র‌্যাম দ্বারা সীমাবদ্ধ এবং হার্ড-ড্রাইভের স্থান নয়। নুব প্রশ্নের জন্য দুঃখিত এবং আপনাকে সাহায্য করার জন্য ধন্যবাদ। আমি তোমার বই উপভোগ করছি
জেলাজনি 7

4
ঠিক আছে, আপনি র‌্যাম দ্বারা সীমাবদ্ধ। "আউট-অফ-কোর" বিগ ডেটা প্রসেসিংয়ের জন্য এসএএসের প্রকৃতপক্ষে আরও ভাল সমর্থন রয়েছে।
ওয়েজ ম্যাককিনি

4
@ ওয়েজমিসকিন্নি এই নতুন কাজের দরকার নেই, কারণ আপনি নতুন সিএসভি লোডারটি 0.10 এ পৌঁছেছেন, তাই না?
গ্যাব্রিয়েল গ্রান্ট

82

ওয়েস অবশ্যই ঠিক! আমি কেবল আরও কিছু সম্পূর্ণ উদাহরণ কোড সরবরাহ করতে চিমিং করছি। আমার 129 এমবি ফাইল নিয়ে একই সমস্যা ছিল, যা এর দ্বারা সমাধান করা হয়েছিল:

import pandas as pd

tp = pd.read_csv('large_dataset.csv', iterator=True, chunksize=1000)  # gives TextFileReader, which is iterable with chunks of 1000 rows.
df = pd.concat(tp, ignore_index=True)  # df is DataFrame. If errors, do `list(tp)` instead of `tp`

6
আমার মনে হয় তুমি কি করতে পার df = concate(tp, ignore_index=True)?
অ্যান্ডি হেডেন

@ এসএমসি একই তথ্য পুনরাবৃত্তি x4 (550 এমবি) বা এক্স 8 (1.1 জিবি) দিয়ে এটি চেষ্টা করে। মজার বিষয় হল, সাথে [x x x for tp] বা এর বাইরে x4 জরিমানার মধ্য দিয়ে গেছে এবং x8 একটি মেমোরিআরারে ক্র্যাশ হয়েছিল।
চিকিত হয়েছে

4
যখন এটি ব্যবহার আমি এই ত্রুটি পাবেন: AssertionError: first argument must be a list-like of pandas objects, you passed an object of type "TextFileReader"। কোন ধারণা এখানে কি ঘটছে?
যুবরাজ কুমার

4
এই বাগটি 0.14 (শীঘ্রই প্রকাশিত হবে), github.com/pydata/pandas/pull/6941 এ স্থির করা হবে ; <0.14.0 এর জন্য কাজ করতে হবেpd.concat(list(tp), ignore_index=True)
জেফ

4
মানগুলি স্ট্রিং বা শ্রেণীবদ্ধ হলে কী হবে - আমি ত্রুটিটি পাচ্ছি: শ্রেণিবদ্ধ
উপসংহারে

42

এটি একটি পুরানো থ্রেড, তবে আমি কেবল আমার কাজের সমাধানটি এখানে ফেলে দিতে চাই। আমি প্রাথমিকভাবে chunksizeপ্যারামিটারটি চেষ্টা করেছি (এমনকি 10000 এর মতো বেশ কয়েকটি ছোট মান সহ) তবে এটি খুব একটা উপকারে আসেনি; মেমরির আকার নিয়ে এখনও প্রযুক্তিগত সমস্যা ছিল (আমার সিএসভি ~ 7.5 জিবি ছিল))

এই মুহুর্তে, আমি কেবলমাত্র সিএসভি ফাইলগুলির একটি অংশ একটি লুপ পদ্ধতির জন্য পড়েছি এবং সেগুলি উদাহরণস্বরূপ, একটি এসকিউএল ডাটাবেস ধাপে ধাপে যুক্ত করেছি:

import pandas as pd
import sqlite3
from pandas.io import sql
import subprocess

# In and output file paths
in_csv = '../data/my_large.csv'
out_sqlite = '../data/my.sqlite'

table_name = 'my_table' # name for the SQLite database table
chunksize = 100000 # number of lines to process at each iteration

# columns that should be read from the CSV file
columns = ['molecule_id','charge','db','drugsnow','hba','hbd','loc','nrb','smiles']

# Get number of lines in the CSV file
nlines = subprocess.check_output('wc -l %s' % in_csv, shell=True)
nlines = int(nlines.split()[0]) 

# connect to database
cnx = sqlite3.connect(out_sqlite)

# Iteratively read CSV and dump lines into the SQLite table
for i in range(0, nlines, chunksize):

    df = pd.read_csv(in_csv,  
            header=None,  # no header, define column header manually later
            nrows=chunksize, # number of rows to read at each iteration
            skiprows=i)   # skip rows that were already read

    # columns to read        
    df.columns = columns

    sql.to_sql(df, 
                name=table_name, 
                con=cnx, 
                index=False, # don't use CSV file index
                index_label='molecule_id', # use a unique column from DataFrame as index
                if_exists='append') 
cnx.close()    

4
খাঁটি পড়া বৈশিষ্ট্যের জন্য একটি বাস্তবসম্মত ব্যবহার-কেস দেখতে সুপার দরকারী। ধন্যবাদ
অ্যালেক্স কেস্টনার

4
এই পুরানো বিষয়টির জন্য কেবলমাত্র একটি ছোট মন্তব্য: pandas.read_csvযদি আপনি সহজভাবে সরবরাহ করেন iterator=Trueএবং সরবরাহ করেন তবে প্রত্যক্ষভাবে (কমপক্ষে আমি বর্তমানে যে সংস্করণটি ব্যবহার করছি তাতে) অন্তর্ভুক্ত হয় chunksize=chunksize। সুতরাং, আপনি প্রতিবার এটি পুনরায় ইনস্ট্যান্ট করার পরিবর্তে forকেবলমাত্র pd.read_csvকলটির উপরে একটি লুপ করবেন । তবে এটির জন্য কেবলমাত্র কল ওভারহেড ব্যয় হয়, সম্ভবত কোনও উল্লেখযোগ্য প্রভাব নেই।
জোল

4
হাই, জোয়েল নোটের জন্য ধন্যবাদ! iterator=Trueএবং chunksizeপরামিতি ইতিমধ্যে তখন অস্তিত্ব যদি আমি সঠিকভাবে মনে রাখবেন। সম্ভবত কোনও পুরানো সংস্করণে একটি ত্রুটি ছিল যা মেমোরিটি ফুটিয়ে তুলেছিল - আমি পরের বার পান্ডাসে একটি বড় ডেটা ফ্রেম পড়ার জন্য আবার চেষ্টা করব (আমি বেশিরভাগ ধরণের কাজগুলির জন্য এখন ব্লেজ ব্যবহার করছি)

6

নীচে আমার কাজের প্রবাহ রয়েছে।

import sqlalchemy as sa
import pandas as pd
import psycopg2

count = 0
con = sa.create_engine('postgresql://postgres:pwd@localhost:00001/r')
#con = sa.create_engine('sqlite:///XXXXX.db') SQLite
chunks = pd.read_csv('..file', chunksize=10000, encoding="ISO-8859-1",
                     sep=',', error_bad_lines=False, index_col=False, dtype='unicode')

আপনার ফাইলের আকারের ভিত্তিতে, আপনি চুনসাইজকে আরও ভাল করতে পারেন।

 for chunk in chunks:
        chunk.to_sql(name='Table', if_exists='append', con=con)
        count += 1
        print(count)

ডেটাবেসে সমস্ত ডেটা থাকার পরে, আপনি ডাটাবেস থেকে আপনার যা প্রয়োজন তা জিজ্ঞাসা করতে পারেন।


3

আপনি যদি বিশাল সিএসভি ফাইল লোড করতে চান তবে ড্যাস্ক একটি ভাল বিকল্প হতে পারে। এটি পান্ডাস এপি নকল করে, তাই এটি পান্ডার সাথে বেশ মিল খুঁজে পায়

গিথুব এ ড্যাস্কের লিঙ্ক


ধন্যবাদ, যেহেতু আমি এটি পোস্ট করেছি আমি ড্যাস্ক এবং কাঠের কাঠামো ফর্ম্যাটটি ব্যবহার করছি।
জেলাজনি

1

আপনি পান্ডেস ডিএফের চেয়ে পিটেবেল ব্যবহার করতে পারেন। এটি বড় ডেটা সেটগুলির জন্য ডিজাইন করা হয়েছে এবং ফাইল ফর্ম্যাটটি এইচডিএফ 5 এ রয়েছে। সুতরাং প্রক্রিয়াজাতকরণ সময় তুলনামূলকভাবে দ্রুত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.