PySpark:如何以表格形式显示 Spark 数据框

92
我正在使用pyspark读取一个像下面这样的parquet文件:
my_df = sqlContext.read.parquet('hdfs://myPath/myDB.db/myTable/**')

当我使用my_df.take(5)时,它会显示[Row(...)]而不是像使用pandas数据框时一样的表格格式。

是否有可能以表格格式显示数据框,就像使用pandas数据框一样?谢谢!


8
请尝试执行以下代码:my_df.take(5).show() - MaxU - stand with Ukraine
我遇到了错误:<ipython-input-14-d14c0ee9b9fe> in <module>() ----> my_df.take(5).show()AttributeError: 'list'对象没有'show'属性。 - Edamame
2
my_df.show().take(5)应该是返回的翻译文本。 - maxymoo
1
@MaxU,.take(5).show()和.show(5)有什么不同?它更快吗? - user2205916
my_df.show(5) #5是行数。 - Palash Mondal
7个回答

114

show方法可以实现您要查找的内容。

例如,给定以下3行数据框,我可以仅打印前两行:

df = sqlContext.createDataFrame([("foo", 1), ("bar", 2), ("baz", 3)], ('k', 'v'))
df.show(n=2)

得到:

+---+---+
|  k|  v|
+---+---+
|foo|  1|
|bar|  2|
+---+---+
only showing top 2 rows

9
它与pandas相比非常原始:例如,对于包装而言它不允许水平滚动。 - WestCoastProjects
谢谢您的回答!但是,链接似乎已经失效了。 - sotmot
感谢提醒。已将链接更新为指向新文档位置。 - eddies

37

假设我们有以下的Spark DataFrame:

df = sqlContext.createDataFrame(
    [
        (1, "Mark", "Brown"), 
        (2, "Tom", "Anderson"), 
        (3, "Joshua", "Peterson")
    ], 
    ('id', 'firstName', 'lastName')
)

通常有三种方式可以用来打印数据框的内容:

打印 Spark 数据框

最常见的方法是使用show()函数:

>>> df.show()
+---+---------+--------+
| id|firstName|lastName|
+---+---------+--------+
|  1|     Mark|   Brown|
|  2|      Tom|Anderson|
|  3|   Joshua|Peterson|
+---+---------+--------+

纵向打印Spark DataFrame

假设你有很多列且数据框无法适应屏幕大小。你可以纵向打印行 - 例如,以下命令将垂直打印顶部两行而不截断任何内容。

>>> df.show(n=2, truncate=False, vertical=True)
-RECORD 0-------------
 id        | 1        
 firstName | Mark     
 lastName  | Brown    
-RECORD 1-------------
 id        | 2        
 firstName | Tom      
 lastName  | Anderson 
only showing top 2 rows

转换为Pandas并打印Pandas DataFrame

或者,您可以使用.toPandas()将Spark DataFrame转换为Pandas DataFrame,最后使用print()进行打印。

>>> df_pd = df.toPandas()
>>> print(df_pd)
   id firstName  lastName
0   1      Mark     Brown
1   2       Tom  Anderson
2   3    Joshua  Peterson

请注意,在处理相当大的数据框时,不建议使用此方法,因为Pandas需要将所有数据加载到内存中。如果是这种情况,以下配置将有助于将大型Spark数据帧转换为Pandas数据帧:

spark.conf.set("spark.sql.execution.arrow.pyspark.enabled", "true")

更多细节请参考我的博客文章如何高效地在PySpark和Pandas DataFrames之间转换


33

正如@Brent在@maxymoo回答的评论中提到的,您可以尝试

df.limit(10).toPandas()

为了在Jupyter中获得一个更漂亮的表格。但是如果您没有缓存Spark DataFrame,这可能需要一些时间才能运行。另外,.limit()不会保留原始Spark DataFrame的顺序。


3
如果您正在使用toPandas(),请考虑启用PyArrow优化:https://medium.com/@giorgosmyrianthous/how-to-efficiently-convert-a-pyspark-dataframe-to-pandas-8bda2c3875c3 - Giorgos Myrianthous

9

是的:在你的数据框上调用toPandas方法,你会得到一个实际的 pandas 数据框!


1
我试图执行my_df.toPandas().head()。但是出现了错误:Py4JJavaError: 调用z:org.apache.spark.api.python.PythonRDD.collectAndServe时发生错误。 org.apache.spark.SparkException: 由于阶段失败而中止作业:任务2.0中的301号在1次内失败,最近一次失败:在阶段2.0中丢失任务301.0(TID 1871,localhost):java.lang.OutOfMemoryError:Java堆空间 - Edamame
11
这很危险,因为它将整个数据框收集到单个节点中。 - David Arenburg
2
应强调的是,在传统的Spark RDD场景中,这将很快耗尽内存。 - deepelement
14
应该使用限制,例如 df.limit(10).toPandas(),以防止OOM。 - Brent
使用 .toPandas() 方法时,我遇到了以下错误:调用 o86.get 时发生错误。 : java.util.NoSuchElementException: spark.sql.execution.pandas.respectSessionTimeZone我该如何处理? - M PAUL
显示剩余2条评论

3

默认情况下,show()函数会打印DataFrame的20条记录。您可以通过向show()函数提供参数来定义要打印的行数。由于您永远不知道DataFrame将具有多少行,因此我们可以将df.count()作为show函数的参数传递,这将打印DataFrame的所有记录。

df.show()           --> prints 20 records by default
df.show(30)         --> prints 30 records according to argument
df.show(df.count()) --> get total row count and pass it as argument to show

0
如果您正在使用Jupyter,以下是我的解决方案:
[1] df = spark.read.parquet("s3://df/*")
[2] dsp = users
[3] %%display dsp 这将显示格式良好的HTML表格,您还可以立即在其上绘制一些简单的图表。有关更多“%%display”的文档,请键入“%%help”。

什么是dsp=users?它与df有什么关系? - Blue Clouds
能否确认它是否与dsp=df兼容? 我猜我只是犯了一个错误,现在没有Jupyter来验证。 - Hubert

-1
也许像这样会更加优雅一些:

df.display()
# OR
df.select('column1').display()

显示不是一个函数,PySpark提供了像head,tail,show这样的函数来显示数据帧。 - bhargav3vedi
请重新阅读问题。答案非常适合它。 - Marc88
pyspark.sql.DataFrame类中没有display()函数。 - Kashyap

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