Pyspark:是否有与pandas info()相当的方法?

13

在PySpark中是否存在与pandas info()方法等效的方法?

我正在尝试获取关于PySpark数据框的基本统计信息,例如: 列数和行数 空值数量 数据框大小

pandas的info()方法提供了所有这些统计信息。

5个回答

8

此外,还有summary方法可用于获取行数和其他描述性统计信息。它类似于已经提到的describe方法。

来自PySpark手册

df.summary().show()
+-------+------------------+-----+
|summary|               age| name|
+-------+------------------+-----+
|  count|                 2|    2|
|   mean|               3.5| null|
| stddev|2.1213203435596424| null|
|    min|                 2|Alice|
|    25%|                 2| null|
|    50%|                 2| null|
|    75%|                 5| null|
|    max|                 5|  Bob|
+-------+------------------+-----+

or

df.select("age", "name").summary("count").show()
+-------+---+----+
|summary|age|name|
+-------+---+----+
|  count|  2|   2|
+-------+---+----+

1
这是pandas的describe()相当于而不是info()相当于。要使用info(),只需执行df.printSchema()。 - Yavar

4

如果需要了解数据帧的类型信息,可以尝试使用 df.schema 命令。

spark.read.csv('matchCount.csv',header=True).printSchema()

StructType(List(StructField(categ,StringType,true),StructField(minv,StringType,true),StructField(maxv,StringType,true),StructField(counts,StringType,true),StructField(cutoff,StringType,true)))

对于概要统计信息,您还可以查看文档中的描述方法。


4
printSchema()会给您提供一个更易读的版本,包含相同的信息。 - Ryan Widmaier
1
请将答案更改为使用 printSchema() :) - Konstantin

4
我找不到好的答案,所以我使用了有点作弊的"最初的回答"。
dataFrame.toPandas().info()

1
你尝试过在大数据集上使用这个吗?我认为只有当整个Spark dataframe可以适应单台机器的内存时,dataFrame.toPandas()才能正常工作。 - user3897315
1
是的,你可能是对的。关注考拉(Koala)的分布式实现熊猫(Panda)的API-https://koalas.readthedocs.io/en/latest/。如果有人有更好的方法提供像.info()一样详细的信息,我想知道,因为这是我错过的少数Panda方法之一。 - Rodney
非常感谢关于考拉的提示。我一定会密切关注。 - user3897315
通过这个答案,你只看到了默认的pandas映射类型,而不是本机spark类型。 - Wassadamo

3
我编写了一个pyspark函数,模拟Pandas.DataFrame.info()函数。
from collections import Counter

def spark_info(df, abbreviate_columns=True, include_nested_types=False, count=None):
    """Similar to Pandas.DataFrame.info which produces output like:
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 201100 entries, 0 to 201099
    Columns: 151 entries, first_col to last_col
    dtypes: float64(20), int64(6), object(50)
    memory usage: 231.7+ MB
    """
    classinfo = "<class 'pyspark.sql.dataframe.DataFrame'>"

    _cnt = count if count else df.count()
    numrows = f"Total Rows: {str(_cnt)}"

    _cols = (
        ', to '.join([
            df.columns[0], df.columns[-1]]) 
        if abbreviate_columns 
        else ', '.join(df.columns))
    columns = f"{len(df.columns)} entries: {_cols}"

    _typs = [
        col.dataType 
        for col in df.schema 
        if include_nested_types or (
            'ArrayType' not in str(col.dataType) and 
            'StructType' not in str(col.dataType) and
            'MapType' not in str(col.dataType))
    ]
    dtypes = ', '.join(
        f"{str(typ)}({cnt})" 
        for typ, cnt in Counter(_typs).items())

    mem = f'memory usage: ? bytes'

    return '\n'.join([classinfo, numrows, columns, dtypes, mem])

我不确定如何估计pyspark dataframe的大小。这取决于完整的spark执行计划和配置,但也许可以尝试这个答案来获得一些想法。

请注意,默认情况下不包括所有dtype摘要,嵌套类型被排除在外。另外,df.count()是计算出来的,这可能需要一些时间,除非您先计算并传入。

建议用法:

>>> df = spark.createDataFrame(((1, 'a', 2),(2,'b',3)), ['id', 'letter', 'num'])
>>> print(spark_info(df, count=2))

<class 'pyspark.sql.dataframe.DataFrame'>
Total Rows: 2
3 entries: id, to num
LongType(2), StringType(1)
memory usage: ? bytes

3

查看这个答案,获取null和非null值的计数。

from pyspark.sql.functions import isnan, when, count, col
import numpy as np

df = spark.createDataFrame(
    [(1, 1, None), (1, 2, float(5)), (1, 3, np.nan), (1, 4, None), (1, 5, float(10)), (1, 6, float('nan')), (1, 6, float('nan'))],
    ('session', "timestamp1", "id2"))

df.show()
# +-------+----------+----+
# |session|timestamp1| id2|
# +-------+----------+----+
# |      1|         1|null|
# |      1|         2| 5.0|
# |      1|         3| NaN|
# |      2|         4|null|
# |      1|         5|10.0|
# |      1|         6| NaN|
# |      1|         6| NaN|
# +-------+----------+----+

df.select([count(when(isnan(c), c)).alias(c) for c in df.columns]).show()
# +-------+----------+---+
# |session|timestamp1|id2|
# +-------+----------+---+
# |      0|         0|  3|
# +-------+----------+---+

df.select([count(when(isnan(c) | col(c).isNull(), c)).alias(c) for c in df.columns]).show()
# +-------+----------+---+
# |session|timestamp1|id2|
# +-------+----------+---+
# |      0|         0|  5|
# +-------+----------+---+

df.describe().show()
# +-------+-------+------------------+---+
# |summary|session|        timestamp1|id2|
# +-------+-------+------------------+---+
# |  count|      7|                 7|  5|
# |   mean|    1.0| 3.857142857142857|NaN|
# | stddev|    0.0|1.9518001458970662|NaN|
# |    min|      1|                 1|5.0|
# |    max|      1|                 6|NaN|
# +-------+-------+------------------+---

我不知道是否有与 pandas.DataFrame.info() 等效的函数。

PrintSchema 很有用,对于小型数据框,可以使用 toPandas.info() 但是当我使用 pandas.DataFrame.info()时,更多关注空值信息。


1
isnan does not support dtypes other than numeric types. The following is more general:df.select([F.sum(F.col(c).isNull().cast(T.IntegerType())).alias(c) for c in df.columns]).show() - ottovon

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