Geo*_*oel 5 python pandas apache-spark parquet
我提取数据仓库中的数据,将其存储在Parquet文件中,然后将所有Parquet文件加载到spark数据框中。到目前为止,一切都很好。但是,当我尝试使用pandas.plot()函数对其进行绘制时,会抛出“ TypeError:空'DataFrame':没有要绘制的数字数据”
因此,我开始向后调查源代码,我认为从初始sql语句转换为十进制是问题之一。但是我不知道如何解决这个问题。我以为fillna(0)可以解决问题,但事实并非如此。
步骤1:定义SQL语句以提取数据
mpr_sql = """
select
CAST(DATE_KEY AS INTEGER) AS DATE_KEY ,
CAST(AMD AS INTEGER) AS AMD ,
CAST(AMD_2 AS DECIMAL(12,2)) AS AMD_2 ,
CAST(AMD_3 AS DECIMAL(12,2)) AS AMD_3 ,
CAST(AMD_4 AS DECIMAL(12,2)) AS AMD_4 ,
CAST(AMD_0 AS DECIMAL(12,2)) AS AMD_0
"""
Run Code Online (Sandbox Code Playgroud)
步骤2:根据提取的数据创建一个Spark数据框
df1 = sqlContext.load(source="jdbc",
driver="com.teradata.jdbc.TeraDriver",
url=db_url,
user=db_user
TMODE="TERA",
password=db_pwd,
dbtable="( "+sql+") a")
Run Code Online (Sandbox Code Playgroud)
步骤3:将spark数据帧存储在具有10个分区的镶木地板文件中
df1.coalesce(10).write.parquet("./mpr"+month+"sorted.parquet")
df = sqlContext.read.parquet('./mpr*sorted.parquet')
Run Code Online (Sandbox Code Playgroud)
步骤4:查看spark数据框架构(显示十进制(12,2))
df.printSchema()
root
|-- DATE_KEY: integer (nullable = true)
|-- AMD: integer (nullable = true)
|-- AMD_2: decimal(12,2) (nullable = true)
|-- AMD_3: decimal(12,2) (nullable = true)
|-- AMD_4: decimal(12,2) (nullable = true)
|-- AMD_0: decimal(12,2) (nullable = true)
Run Code Online (Sandbox Code Playgroud)
步骤5:将spark数据框转换为pandas数据框,并将所有Null替换为0(使用fillna(0))
pdf=df.fillna(0).toPandas()
Run Code Online (Sandbox Code Playgroud)
步骤6:查看相关列的pandas数据框信息。AMD是正确的(整数),但是AMD_4是我希望使用double或float或类似名称的对象类型(对不起,总是忘记正确的类型)。而且由于AMD_4是非数字类型,因此无法使用它进行绘制。
pdf[['AMD','AMD4']].info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 20 entries, 20140101 to 20150801
Data columns (total 2 columns):
AMD 20 non-null int64
AMD_4 20 non-null object
dtypes: int64(1), object(1)
memory usage: 480.0+ bytes
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
小智 9
我遇到了同样的问题,然后我想出了是什么原因。
在转换过程中,有数据类型的合并,例如int/long -> int64,double -> float64,string->obj。对于所有未知的数据类型,都会转换为 obj 类型。
在 Pandas 数据框中,没有十进制数据类型,因此所有十进制数据类型的列都转换为 obj 类型。
如果您可以在应用 toPandas() 之前将所有十进制数据类型转换为双精度类型,那么您将可以使用所有数字数据。
from pyspark.sql.functions import *
from pyspark.sql.types import *
df = df.withColumn('AMD_4', col('AMD_4').cast(DoubleType())).withColumn('AMD_2', col('AMD_2').cast(DoubleType()))
pdf = df.toPandas()
Run Code Online (Sandbox Code Playgroud)
在 pdf 中,AMD_4 和 AMD_2 现在将是数字。
首先检查pdf.isnull().sum():
1.应该全部为零。由于某种原因,如果某些列计数返回 na 或 nan,您始终可以使用 pandas fillna(),
pdf = df.fillna(0).toPandas()
pdf = pdf.fillna(0)
Run Code Online (Sandbox Code Playgroud)
或者
pdf=df.toPandas().fillna(0)
Run Code Online (Sandbox Code Playgroud)
2.如果全部为零,则检查类型不匹配的位置,
pdf.applymap(lambda x: isinstance(x, (int, float)))
Run Code Online (Sandbox Code Playgroud)
并改正它
| 归档时间: |
|
| 查看次数: |
7051 次 |
| 最近记录: |