স্পার্কের সাথে সিএসভি ফাইল লোড করুন


110

আমি স্পার্কে নতুন এবং আমি স্পার্ক সহ একটি ফাইল থেকে সিএসভি ডেটা পড়ার চেষ্টা করছি। আমি যা করছি তা এখানে:

sc.textFile('file.csv')
    .map(lambda line: (line.split(',')[0], line.split(',')[1]))
    .collect()

আমি এই কলটি আমার ফাইলের প্রথম দুটি কলামের একটি তালিকা দেবে বলে আমি আশা করব তবে আমি এই ত্রুটিটি পাচ্ছি:

File "<ipython-input-60-73ea98550983>", line 1, in <lambda>
IndexError: list index out of range

যদিও আমার সিএসভি ফাইল একাধিক কলাম হিসাবে রয়েছে।

উত্তর:


63

আপনি কি নিশ্চিত যে সমস্ত লাইনে কমপক্ষে 2 টি কলাম রয়েছে? আপনি কি পরীক্ষা করার মতো কিছু চেষ্টা করতে পারেন?:

sc.textFile("file.csv") \
    .map(lambda line: line.split(",")) \
    .filter(lambda line: len(line)>1) \
    .map(lambda line: (line[0],line[1])) \
    .collect()

বিকল্পভাবে, আপনি অপরাধীকে মুদ্রণ করতে পারেন (যদি থাকে):

sc.textFile("file.csv") \
    .map(lambda line: line.split(",")) \
    .filter(lambda line: len(line)<=1) \
    .collect()

এটি ছিল, কেবল একটি কলাম সহ একটি লাইন, আপনাকে ধন্যবাদ।
কেরনেল

2
csvসমস্ত অবতরণ পরিচালনা করার জন্য অন্তর্নির্মিত গ্রন্থাগারটি ব্যবহার করে পার্স করা ভাল কারণ কেবল কমা দ্বারা বিভাজন কাজ করবে না যদি, বলুন, মানগুলিতে কমা রয়েছে।
sudo

4
সিএসভি পার্স করার জন্য প্রচুর সরঞ্জাম রয়েছে, চাকাটি পুনর্বিবেচনা করবেন না
স্টিফেন

2
কোটের ভিতরে কমা থাকলে এই কোডটি ভেঙে যাবে। সিএসভি পার্সিং করা কেবলমাত্র বিভাজনের চেয়ে জটিল ","
Alceu Costa

এটি কমা জন্য বিরতি। এটা খুব খারাপ.
rjurney

184

2.0.0+ স্পার্ক করুন ark

আপনি সরাসরি অন্তর্নির্মিত সিএসভি ডেটা উত্স ব্যবহার করতে পারেন:

spark.read.csv(
    "some_input_file.csv", header=True, mode="DROPMALFORMED", schema=schema
)

অথবা

(spark.read
    .schema(schema)
    .option("header", "true")
    .option("mode", "DROPMALFORMED")
    .csv("some_input_file.csv"))

কোন বাহ্যিক নির্ভরতা অন্তর্ভুক্ত ছাড়া।

স্পার্ক <২.০.০ :

ম্যানুয়াল পার্সিংয়ের পরিবর্তে, যা একটি সাধারণ ক্ষেত্রে তুচ্ছ থেকে দূরে, আমি সুপারিশ করব spark-csv:

নিশ্চিত করুন যে স্পার্ক করা CSV পথ মধ্যে অন্তর্ভুক্ত করা হয় তোলার জন্য ( --packages, --jars, --driver-class-path)

এবং নিম্নলিখিত হিসাবে আপনার ডেটা লোড করুন:

(df = sqlContext
    .read.format("com.databricks.spark.csv")
    .option("header", "true")
    .option("inferschema", "true")
    .option("mode", "DROPMALFORMED")
    .load("some_input_file.csv"))

এটি লোডিং, স্কিমা অনুমান, ত্রুটিযুক্ত লাইনগুলি হ্যান্ডল করতে পারে এবং পাইথন থেকে জেভিএমে ডেটা পাস করার প্রয়োজন হয় না।

দ্রষ্টব্য :

যদি আপনি স্কিমাটি জানেন তবে স্কিমা অনুমিতি এড়ানো এবং এটিকে দেওয়া ভাল DataFrameReader। ধরে নিলাম আপনার কাছে তিনটি কলাম রয়েছে - পূর্ণসংখ্যা, ডাবল এবং স্ট্রিং:

from pyspark.sql.types import StructType, StructField
from pyspark.sql.types import DoubleType, IntegerType, StringType

schema = StructType([
    StructField("A", IntegerType()),
    StructField("B", DoubleType()),
    StructField("C", StringType())
])

(sqlContext
    .read
    .format("com.databricks.spark.csv")
    .schema(schema)
    .option("header", "true")
    .option("mode", "DROPMALFORMED")
    .load("some_input_file.csv"))

6
আপনি যদি এটি করেন, আপনি পাইপার্ক শেলটি খুললে বা স্পার্ক-সাবমিট ব্যবহার করার সময় ডেটাব্রিকস সিএসভি প্যাকেজটি অন্তর্ভুক্ত করতে ভুলবেন না। উদাহরণস্বরূপ, pyspark --packages com.databricks:spark-csv_2.11:1.4.0(আপনি যেগুলি ইনস্টল করেছেন তার সাথে ডেটাব্রিকস / স্পার্ক সংস্করণগুলি পরিবর্তন করতে ভুলবেন না)।
গ্যালেন লং

এটি কি সিএসভি কনটেক্সট বা স্কাইলকন্টেক্সট পিসপার্কে? কারণ স্কেলে আপনার csvContext দরকার
জেফ্রি অ্যান্ডারসন

28
from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .appName("Python Spark SQL basic example") \
    .config("spark.some.config.option", "some-value") \
    .getOrCreate()

df = spark.read.csv("/home/stp/test1.csv",header=True,sep="|");

print(df.collect())

'সেপ না' বিভাজক 'নিম্নরূপে ব্যবহার করুন: df = spark.read.csv ("/ home / stp / test1.csv", শিরোনাম = সত্য, sep = "|")
গ্রান্ট শ্যানন

18

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

উদাহরণ স্বরূপ:

from pyspark import SparkContext
from pyspark.sql import SQLContext
import pandas as pd

sc = SparkContext('local','example')  # if using locally
sql_sc = SQLContext(sc)

pandas_df = pd.read_csv('file.csv')  # assuming the file contains a header
# pandas_df = pd.read_csv('file.csv', names = ['column 1','column 2']) # if no header
s_df = sql_sc.createDataFrame(pandas_df)

7
ওপি যদি
পান্ডায়

প্রতিটি স্পার্ক ক্লাস্টারে নির্ভরতা ইনস্টল করতে বা নির্দিষ্ট করতে চান না ....
সামারেলা

পান্ডা পড়ার সময় ফাইল ছাঁটাইকে অনুমতি দেয় তাই পান্ডাস প্রাথমিক ফাইল পার্সিং হ্যান্ডেল করার জন্য এখানে এখনও ব্যবহারের কেস রয়েছে। কোডের জন্য আমার উত্তরটি নীচে দেখুন।
এবি sobh

সতর্কতা: পান্ডস স্পার্কের চেয়ে কলাম কমা স্কিমার পদ্ধতিতেও বিশেষভাবে পরিচালনা করে বিশেষত যখন ফাঁকা অংশ জড়িত থাকে। প্রতিটি কলামের স্ট্রিং হিসাবে কেবল সিএসভি লোড করা নিরাপদ।
এন্টিপোন7979

@ উডচ্যাপার আপনি স্পার্কে ইউডিএফ হিসাবে পান্ডাস ব্যবহার করতে পারেন, না?
ফ্লো

16

কেবলমাত্র কমা দ্বারা বিভক্ত করা ক্ষেত্রগুলির মধ্যে থাকা কমাগুলিও বিভক্ত হবে (উদাহরণস্বরূপ a,b,"1,2,3",c), সুতরাং এটি প্রস্তাবিত নয়। zero323 এর উত্তর ভাল আপনি DataFrames এপিআই ব্যবহার করতে চান, কিন্তু আপনি যদি বেস স্পার্ক বিদ্ধ করতে চাই, আপনার সাথে বেস পাইথন মধ্যে csvs পার্স পারেন হয় যদি CSV মডিউল:

# works for both python 2 and 3
import csv
rdd = sc.textFile("file.csv")
rdd = rdd.mapPartitions(lambda x: csv.reader(x))

সম্পাদনা: @ মুমন মন্তব্যে যেমন উল্লেখ করেছেন, এটি শিরোনামকে অন্য কোনও সারির মতো আচরণ করবে যাতে আপনাকে এটি ম্যানুয়ালি বের করতে হবে। উদাহরণস্বরূপ, header = rdd.first(); rdd = rdd.filter(lambda x: x != header)( headerফিল্টার মূল্যায়নের আগে সংশোধন না করার বিষয়টি নিশ্চিত করুন )। তবে এই মুহুর্তে, আপনি অন্তর্নির্মিত সিএসভি পার্সার ব্যবহার করে আরও ভাল।


1
ডেটা ফ্রেমগুলি ব্যবহার করার জন্য আপনার মাইভের দরকার নেই। আপনার সমাধান সম্পর্কে: ক) প্রয়োজন নেই StringIOcsvযে কোনও পুনরাবৃত্তযোগ্য ব্যবহার করতে পারে খ) __next__সরাসরি ব্যবহার করা উচিত নয় এবং খালি লাইনে ব্যর্থ হবে। ফ্ল্যাটম্যাপটি দেখুন গ) mapPartitionsপ্রতিটি লাইনে পাঠককে আরম্ভ করার পরিবর্তে এটি ব্যবহার করা আরও বেশি দক্ষ হবে :)
শূন্য 323

সংশোধনের জন্য অনেক ধন্যবাদ! আমি আমার উত্তর সম্পাদনা করার আগে আমি নিশ্চিত হয়েছি যে আমি পুরোপুরি বুঝতে পেরেছি। 1) ত্রুটি নিক্ষেপ rdd.mapPartitions(lambda x: csv.reader(x))করার সময় কেন কাজ করে rdd.map(lambda x: csv.reader(x))? আমি উভয় একই নিক্ষেপ আশা করি TypeError: can't pickle _csv.reader objects। এটি মনে হয় যেন mapPartitionsস্বয়ংক্রিয়ভাবে কোনও csv.readerঅবজেক্টে "রিডলাইনস" এর সমতুল্য কল করে , যেখানে এর সাথে তালিকাগুলি বের করার mapজন্য আমার __next__স্পষ্টভাবে কল করা দরকার csv.reader। 2) কোথায় flatMapআসে? শুধু mapPartitionsএকা কলিং আমার পক্ষে কাজ করেছিল।
গ্যালেন লং

1
rdd.mapPartitions(lambda x: csv.reader(x))কাজ করে কারণ mapPartitionsএকটি Iterableবস্তুর প্রত্যাশা করে । আপনি যদি স্পষ্ট হতে চান তবে আপনি বুঝতে বা জেনারেটরের অভিব্যক্তিটি করতে পারেন। mapএকা কাজ করে না কারণ এটি বস্তুর উপরে পুনরাবৃত্তি করে না। সুতরাং আমার ব্যবহারের পরামর্শ flatMap(lambda x: csv.reader([x]))যা পাঠকের উপরে পুনরাবৃত্তি হবে। তবে mapPartitionsএখানে অনেক ভাল।
শূন্য323

1
নোট করুন যে এটি শিরোনাম হিসাবে ডেটা সারি হিসাবে শিরোনাম পড়বে
মুওন

7

এটি পিওয়াইএসপিআরকে

path="Your file path with file name"

df=spark.read.format("csv").option("header","true").option("inferSchema","true").load(path)

তারপরে আপনি চেক করতে পারেন

df.show(5)
df.count()

6

আপনি যদি ডেটাফ্রেম হিসাবে সিএসভি লোড করতে চান তবে নিম্নলিখিতগুলি করতে পারেন:

from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)

df = sqlContext.read.format('com.databricks.spark.csv') \
    .options(header='true', inferschema='true') \
    .load('sampleFile.csv') # this is your csv file

এটা আমার জন্য ভাল কাজ করেছিল.


@ গ্যালেনলং যদি আপনি কিছু মনে করেন না, আপনি কি ইতিমধ্যে বিদ্যমান উত্তরটি ভাগ করতে পারেন
জেরিল

অদ্ভুত, আমি শপথ করছি এই সমাধানের সাথে আরও একটি উত্তর ছিল। সম্ভবত আমি এটি অন্য একটি প্রশ্নের সাথে বিভ্রান্ত হয়ে পড়েছি। আমার খারাপ।
গ্যালেন লং

5

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

from pyspark import SparkContext
from pyspark.sql import SQLContext
import pandas as pd

sc = SparkContext('local','example')  # if using locally
sql_sc = SQLContext(sc)

Spark_Full = sc.emptyRDD()
chunk_100k = pd.read_csv("Your_Data_File.csv", chunksize=100000)
# if you have headers in your csv file:
headers = list(pd.read_csv("Your_Data_File.csv", nrows=0).columns)

for chunky in chunk_100k:
    Spark_Full +=  sc.parallelize(chunky.values.tolist())

YourSparkDataFrame = Spark_Full.toDF(headers)
# if you do not have headers, leave empty instead:
# YourSparkDataFrame = Spark_Full.toDF()
YourSparkDataFrame.show()

5

এখন, যে কোনও সাধারণ সিএসভি ফাইলের জন্য আরও একটি বিকল্প রয়েছে: https://github.com/seahboonsiew/pyspark-csv নিম্নরূপ:

ধরে নিন আমাদের নীচের প্রসঙ্গ রয়েছে

sc = SparkContext
sqlCtx = SQLContext or HiveContext

প্রথমে স্পার্ককন্টেক্সট ব্যবহার করে এক্সিকিউটিউটরে pyspark-csv.py বিতরণ করুন

import pyspark_csv as pycsv
sc.addPyFile('pyspark_csv.py')

স্পারকনটেক্সট এর মাধ্যমে সিএসভি ডেটা পড়ুন এবং এটি ডেটা ফ্রেমে রূপান্তর করুন

plaintext_rdd = sc.textFile('hdfs://x.x.x.x/blah.csv')
dataframe = pycsv.csvToDataFrame(sqlCtx, plaintext_rdd)

3

যদি আপনার সিএসভি ডেটা কোনও ক্ষেত্রেই নতুন লাইনের উপস্থিতি না ঘটে তবে আপনি নিজের ডেটা লোড করে textFile()পার্স করতে পারেন

import csv
import StringIO

def loadRecord(line):
    input = StringIO.StringIO(line)
    reader = csv.DictReader(input, fieldnames=["name1", "name2"])
    return reader.next()

input = sc.textFile(inputFile).map(loadRecord)

2

যদি আপনার ডেটাসেটে 2 এর চেয়ে কম বা বেশি সংখ্যক কলাম সহ কোনও এক বা একাধিক সারি (গুলি) থাকে তবে এই ত্রুটি দেখা দিতে পারে।

আমি পাইপার্কেও নতুন এবং সিএসভি ফাইলটি পড়ার চেষ্টা করছি। নিম্নলিখিত কোডটি আমার পক্ষে কাজ করেছে:

এই কোডটিতে আমি লিখিতটি কেগল থেকে ডেটাসেটটি ব্যবহার করছি: https://www.kaggle.com/carrie1/ecommerce-data

1. স্কিমার উল্লেখ না করে:

from pyspark.sql import SparkSession  
scSpark = SparkSession \
    .builder \
    .appName("Python Spark SQL basic example: Reading CSV file without mentioning schema") \
    .config("spark.some.config.option", "some-value") \
    .getOrCreate()

sdfData = scSpark.read.csv("data.csv", header=True, sep=",")
sdfData.show()

এখন কলামগুলি দেখুন: sdfData.col ڪالম

আউটপুট হবে:

['InvoiceNo', 'StockCode','Description','Quantity', 'InvoiceDate', 'CustomerID', 'Country']

প্রতিটি কলামের জন্য ডেটাটাইপ পরীক্ষা করুন:

sdfData.schema
StructType(List(StructField(InvoiceNo,StringType,true),StructField(StockCode,StringType,true),StructField(Description,StringType,true),StructField(Quantity,StringType,true),StructField(InvoiceDate,StringType,true),StructField(UnitPrice,StringType,true),StructField(CustomerID,StringType,true),StructField(Country,StringType,true)))

এটি স্ট্রিংটাইপ হিসাবে ডেটাটাইপ সহ সমস্ত কলামের সাথে ডেটা ফ্রেম দেবে

২. স্কিমা সহ: যদি আপনি স্কিমাটি জানেন বা উপরের সারণীতে যে কোনও কলামের ডেটাটাইপ পরিবর্তন করতে চান তবে এটি ব্যবহার করুন (আসুন আমি বলি যে আমার কাছে কলামগুলি নীচে রয়েছে এবং সেগুলির প্রতিটিটির জন্য একটি নির্দিষ্ট ডেটা টাইপ চাই)

from pyspark.sql import SparkSession  
from pyspark.sql.types import StructType, StructField
from pyspark.sql.types import DoubleType, IntegerType, StringType
    schema = StructType([\
        StructField("InvoiceNo", IntegerType()),\
        StructField("StockCode", StringType()), \
        StructField("Description", StringType()),\
        StructField("Quantity", IntegerType()),\
        StructField("InvoiceDate", StringType()),\
        StructField("CustomerID", DoubleType()),\
        StructField("Country", StringType())\
    ])

scSpark = SparkSession \
    .builder \
    .appName("Python Spark SQL example: Reading CSV file with schema") \
    .config("spark.some.config.option", "some-value") \
    .getOrCreate()

sdfData = scSpark.read.csv("data.csv", header=True, sep=",", schema=schema)

এখন প্রতিটি কলামের ডেটাটাইপের জন্য স্কিমা পরীক্ষা করে দেখুন:

sdfData.schema

StructType(List(StructField(InvoiceNo,IntegerType,true),StructField(StockCode,StringType,true),StructField(Description,StringType,true),StructField(Quantity,IntegerType,true),StructField(InvoiceDate,StringType,true),StructField(CustomerID,DoubleType,true),StructField(Country,StringType,true)))

সম্পাদিত: স্কিমার স্পষ্টভাবে উল্লেখ না করে আমরা নিম্নলিখিত কোডের লাইনটি ব্যবহার করতে পারি:

sdfData = scSpark.read.csv("data.csv", header=True, inferSchema = True)
sdfData.schema

আউটপুটটি হ'ল:

StructType(List(StructField(InvoiceNo,StringType,true),StructField(StockCode,StringType,true),StructField(Description,StringType,true),StructField(Quantity,IntegerType,true),StructField(InvoiceDate,StringType,true),StructField(UnitPrice,DoubleType,true),StructField(CustomerID,IntegerType,true),StructField(Country,StringType,true)))

আউটপুটটি দেখতে এইরকম হবে:

sdfData.show()

+---------+---------+--------------------+--------+--------------+----------+-------+
|InvoiceNo|StockCode|         Description|Quantity|   InvoiceDate|CustomerID|Country|
+---------+---------+--------------------+--------+--------------+----------+-------+
|   536365|   85123A|WHITE HANGING HEA...|       6|12/1/2010 8:26|      2.55|  17850|
|   536365|    71053| WHITE METAL LANTERN|       6|12/1/2010 8:26|      3.39|  17850|
|   536365|   84406B|CREAM CUPID HEART...|       8|12/1/2010 8:26|      2.75|  17850|
|   536365|   84029G|KNITTED UNION FLA...|       6|12/1/2010 8:26|      3.39|  17850|
|   536365|   84029E|RED WOOLLY HOTTIE...|       6|12/1/2010 8:26|      3.39|  17850|
|   536365|    22752|SET 7 BABUSHKA NE...|       2|12/1/2010 8:26|      7.65|  17850|
|   536365|    21730|GLASS STAR FROSTE...|       6|12/1/2010 8:26|      4.25|  17850|
|   536366|    22633|HAND WARMER UNION...|       6|12/1/2010 8:28|      1.85|  17850|
|   536366|    22632|HAND WARMER RED P...|       6|12/1/2010 8:28|      1.85|  17850|
|   536367|    84879|ASSORTED COLOUR B...|      32|12/1/2010 8:34|      1.69|  13047|
|   536367|    22745|POPPY'S PLAYHOUSE...|       6|12/1/2010 8:34|       2.1|  13047|
|   536367|    22748|POPPY'S PLAYHOUSE...|       6|12/1/2010 8:34|       2.1|  13047|
|   536367|    22749|FELTCRAFT PRINCES...|       8|12/1/2010 8:34|      3.75|  13047|
|   536367|    22310|IVORY KNITTED MUG...|       6|12/1/2010 8:34|      1.65|  13047|
|   536367|    84969|BOX OF 6 ASSORTED...|       6|12/1/2010 8:34|      4.25|  13047|
|   536367|    22623|BOX OF VINTAGE JI...|       3|12/1/2010 8:34|      4.95|  13047|
|   536367|    22622|BOX OF VINTAGE AL...|       2|12/1/2010 8:34|      9.95|  13047|
|   536367|    21754|HOME BUILDING BLO...|       3|12/1/2010 8:34|      5.95|  13047|
|   536367|    21755|LOVE BUILDING BLO...|       3|12/1/2010 8:34|      5.95|  13047|
|   536367|    21777|RECIPE BOX WITH M...|       4|12/1/2010 8:34|      7.95|  13047|
+---------+---------+--------------------+--------+--------------+----------+-------+
only showing top 20 rows

1

ব্যবহার করার সময় spark.read.csv, আমি দেখতে পেয়েছি যে বিকল্পগুলি ব্যবহার করে escape='"'এবং সিএসভি স্ট্যান্ডার্ডেরmultiLine=True সর্বাধিক ধারাবাহিক সমাধান সরবরাহ করে এবং আমার অভিজ্ঞতায় গুগল পত্রক থেকে রফতানি হওয়া সিএসভি ফাইলগুলির সাথে সবচেয়ে ভাল কাজ করে।

এটাই,

#set inferSchema=False to read everything as string
df = spark.read.csv("myData.csv", escape='"', multiLine=True,
     inferSchema=False, header=True)

স্পার্ক কোথা থেকে এসেছে? এটা import pyspark as sparkকি?
লুক আরন

@ লুকআরন একটি পাইপার্ক শেলটিতে sparkইতিমধ্যে শুরু করা হয়েছে। জমা দেওয়া কোনও স্ক্রিপ্টে spark-submit, আপনি এটিকে তত্ক্ষণাত্ করে দিতে পারেন from pyspark.sql import SparkSession; spark = SparkSession.builder.getOrCreate()
ফ্লো 2 কে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.