Python 3.x 如何在Pyspark spark.sql数据帧中对数据进行同质化
我下载了一个包含AirBnB数据的1.9 GB csv文件。虽然所有列的数据类型都是“string”,但我有一些列不是“同质”的,比如“便利设施”列,其中一些条目包含该特定酒店的便利设施数量,其他条目包含便利设施列表。都是字符串格式 到目前为止,我的情况如下:Python 3.x 如何在Pyspark spark.sql数据帧中对数据进行同质化,python-3.x,pandas,pyspark,pyspark-sql,Python 3.x,Pandas,Pyspark,Pyspark Sql,我下载了一个包含AirBnB数据的1.9 GB csv文件。虽然所有列的数据类型都是“string”,但我有一些列不是“同质”的,比如“便利设施”列,其中一些条目包含该特定酒店的便利设施数量,其他条目包含便利设施列表。都是字符串格式 到目前为止,我的情况如下: from pyspark import SparkContext, SparkConf import pandas as pd import numpy as np conf = SparkConf().setAppName("app")
from pyspark import SparkContext, SparkConf
import pandas as pd
import numpy as np
conf = SparkConf().setAppName("app")
sc = SparkContext(conf=conf)
from pyspark.sql import SQLContext
SQLCtx = SQLContext(sc)
air =SQLCtx.read.load('/home/john/Downloads/airbnb-listings.csv',
format = "com.databricks.spark.csv",
header = "true",
sep = ";",
inferSchema = "true")
#check for missing values
from pyspark.sql.functions import col,sum
air.select(*(sum(col(c).isNull().cast("int")).alias(c) for c in air.columns)).show()
因此,在删除了几列并删除了缺失的值之后,我得到了以下结果:
Keep = ['Price', 'Bathrooms', 'Bedrooms', 'Beds', 'Bed Type', 'Amenities',
'Security Deposit', 'Cleaning Fee', 'Guests Included', 'Extra People',
'Review Scores Rating', 'Cancellation Policy','Host Response Rate',
'Country Code', 'Zipcode']
data = air.select(*Keep)
reduced2 = data.na.drop()
#final shape after dropping missing values.
print((reduced2.count(), len(reduced2.columns)))
我可以将几行转换为一个数据帧:
df3 = pd.DataFrame(reduced2.take(50), columns = reduced2.columns)
“便利设施”列表中的一小部分:
正如你所看到的,我将很难处理这个问题。
我可以很容易地在普通熊猫身上做一些事情来修复它,比如:
for i in range(len(df3['Amenities'])):
if len(df3["Amenities"][i])>2:
df3['Amenities'][i] = str(len(df3['Amenities'][i].split(',')))
现在我意识到这可能不是最好的方法,但它将列表中的所有内容都变成了数字。
如果可能的话,我需要一种对pyspark SQL数据帧中的列执行类似操作的方法
谢谢 我不熟悉PySpark SQL数据帧,只熟悉它
不确定你的任务是什么,但可能考虑把这一列转换成两列。例如(假设这在PySpark中是可能的):
df['professionals\u count']=pd.to\u numeric(df['professionals'],errors='concurve')
用列表=df['professionals\u count']屏蔽条目。isna()
掩码\u条目\u与\u编号=~掩码\u条目\u与\u列表
df.loc[用“便利设施”编号屏蔽项目]=[]
df.loc[用“便利设施”列表屏蔽便利设施条目]=df[“便利设施”]。应用(len)
(未测试)如果我理解正确,您希望计算由
,
分隔的项目数,但保留已经是数字的行。如果是,您可以尝试以下方法:
from pyspark.sql import functions as F
df.withColumn('Amenities'
, F.when(df.Amenities.rlike('^\d+$'), df.Amenities) \
.otherwise(F.size(F.split('Amenities', ","))) \
.astype("string")
).show()
因此,如果列便利设施是一个整数
df.commercies.rlike(“^\d+$”)
,我们将保持其原样df.commercies
,否则,使用F.size()
和F.split()
计算项目数。然后将结果转换为一个“字符串”,它似乎已经完成了这项工作。有一个问题,这部分像(“^\d+$”)是做什么的?我以前没有见过这种情况。@Jabernet,rlike()
是否与正则表达式匹配,请检查文档:。模式^\d+$
表示匹配的值仅包含1个或多个数字[0-9]
,而不包含任何其他字符。
from pyspark.sql import functions as F
df.withColumn('Amenities'
, F.when(df.Amenities.rlike('^\d+$'), df.Amenities) \
.otherwise(F.size(F.split('Amenities', ","))) \
.astype("string")
).show()