![](/img/trans.png)
[英]How can I read a text file from HDFS into Python, and save the content in a string?
[英]How can I read in a binary file from hdfs into a Spark dataframe?
我正在嘗試將一些代碼從 Pandas 移植到 (py)Spark。 不幸的是,我已經在輸入部分失敗了,我想在其中讀取二進制數據並將其放入 Spark Dataframe。
到目前為止,我正在使用來自 numpy 的fromfile
:
dt = np.dtype([('val1', '<i4'),('val2','<i4'),('val3','<i4'),('val4','f8')])
data = np.fromfile('binary_file.bin', dtype=dt)
data=data[1:] #throw away header
df_bin = pd.DataFrame(data, columns=data.dtype.names)
但是對於 Spark,我找不到如何去做。 到目前為止,我的解決方法是使用 csv-Files 而不是二進制文件,但這不是理想的解決方案。 我知道我不應該將 numpy 的fromfile
與 spark fromfile
使用。 如何讀取已加載到 hdfs 中的二進制文件?
我試過類似的東西
fileRDD=sc.parallelize(['hdfs:///user/bin_file1.bin','hdfs:///user/bin_file2.bin])
fileRDD.map(lambda x: ???)
但它給了我一個No such file or directory
錯誤。
我見過這個問題: spark in python: create an rdd by loading binary data with numpy.fromfile但只有當我將文件存儲在驅動程序節點的主目錄中時才有效。
所以,對於像我這樣從 Spark 開始並偶然發現二進制文件的人。 這是我解決它的方法:
dt=np.dtype([('idx_metric','>i4'),('idx_resource','>i4'),('date','>i4'),
('value','>f8'),('pollID','>i2')])
schema=StructType([StructField('idx_metric',IntegerType(),False),
StructField('idx_resource',IntegerType(),False),
StructField('date',IntegerType),False),
StructField('value',DoubleType(),False),
StructField('pollID',IntegerType(),False)])
filenameRdd=sc.binaryFiles('hdfs://nameservice1:8020/user/*.binary')
def read_array(rdd):
#output=zlib.decompress((bytes(rdd[1])),15+32) # in case also zipped
array=np.frombuffer(bytes(rdd[1])[20:],dtype=dt) # remove Header (20 bytes)
array=array.newbyteorder().byteswap() # big Endian
return array.tolist()
unzipped=filenameRdd.flatMap(read_array)
bin_df=sqlContext.createDataFrame(unzipped,schema)
現在你可以用你的數據框在 Spark 中做任何你想做的事情。
編輯:請查看這里提到的 sc.binaryFiles 的使用: https ://stackoverflow.com/a/28753276/5088142
嘗試使用:
hdfs://machine_host_name:8020/user/bin_file1.bin
您是core-site.xml中fs.defaultFS中的主機名
從 Spark 3.0 開始,Spark 支持二進制文件數據源,它讀取二進制文件並將每個文件轉換為包含文件原始內容和元數據的單個記錄。
https://spark.apache.org/docs/latest/sql-data-sources-binaryFile.html
我最近做了這樣的事情:
from struct import unpack_from
# creates an RDD of binaryrecords for determinted record length
binary_rdd = sc.binaryRecords("hdfs://" + file_name, record_length)
# map()s each binary record to unpack() it
unpacked_rdd = binary_rdd.map(lambda record: unpack_from(unpack_format, record))
# registers a data frame with this schema; registerTempTable() it as table_name
raw_df = sqlc.createDataFrame(unpacked_rdd, sparkSchema)
raw_df.registerTempTable(table_name)
其中 unpack_format 和 sparkSchema 必須“同步”。
unpack_format 是 Python 的 unpack() 和 unpack_from() 函數使用的格式,如https://docs.python.org/2/library/struct.html#format-characters 中所述
sparkSchema 是定義數據框架構的變量。 請參閱https://spark.apache.org/docs/1.6.2/api/python/pyspark.sql.html#pyspark.sql.SQLContext.createDataFrame 中的示例
我有一個動態生成 unpack_format 和 sparkSchema 變量的腳本; 兩者同時。 (它是更大代碼庫的一部分,所以不要在這里發布以提高可讀性)
unpack_format 和 sparkSchema 可以定義如下,例如,
from pyspark.sql.types import *
unpack_format = '<' # '<' means little-endian: https://docs.python.org/2/library/struct.html#byte-order-size-and-alignment
sparkSchema = StructType()
record_length = 0
unpack_format += '35s' # 35 bytes that represent a character string
sparkSchema.add("FirstName", 'string', True) # True = nullable
record_length += 35
unpack_format += 'H' # 'H' = unsigned 2-byte integer
sparkSchema.add("ZipCode", 'integer', True)
record_length += 2
# and so on for each field..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.