arrays - 过滤位于 pyspark.sql.dataframe 单元格中的数组
问题描述
我对 PySpark 很陌生,有一些 Python 经验。我已经能够过滤数据帧的行,并编写了 udf,它从 DataFrame 单元格中的数组计算结果,结果为 int 或 double。不,我需要一个数组作为输出,几个小时后我还没有找到一个有用的例子。
这是问题:
DataFrame 具有以下方案,其中 number 是同一 DataFrame 行的数组的条目数:
DataFrame[number: int, code: array<string>, d1: array<double>, d2: array<double>]
这是一个名为 df1 的 DataFrame 示例:
[4 ,['correct', 'correct', 'wrong', 'correct'], [33, 42, 35, 76], [12, 35, 15, 16]]
[2 ,['correct', 'wrong'], [47, 43], [13, 17]]
现在,只有当我在 DataFrame 行的代码列的 i 位置有“正确”时,我才想保留 d1 和 d2 的 i 位置。此外,我想有一个新的 numberNew 剩余的职位数量。生成的结构和 DataFrame“df2”应该如下所示:
DataFrame[number: int, numberNew: int, code: array<string>, d1: array<double>, d2: array<double>]
[4 , 3, ['correct', 'correct', 'correct'], [33, 42, 76], [12, 35, 16]]
[2 , 1, ['correct'], [47], [13]]
在其他几件事中(并且基于 Python 中的成功解决方案),我尝试了以下代码:
def filterDF(number, code, d1, d2):
dataFiltered = []
numberNew = 0
for i in range(number):
if code[i] == 'correct':
dataFiltered.append([d1[i],d2[i]])
countNew += 1
newTable = {'countNew' : countNew, 'data' : dataFiltered}
newDf = pd.DataFrame(newTable)
return newDf
from pyspark.sql.types import ArrayType
filterDFudf = sqlContext.udf.register("filterDF", filterDF, "Array<double>")
df2 = df1.select(df1.number, filterDFudf(df1.number, df1.code, df1.d1, df1.d2)).alias('dataNew')
我收到了一条很长且没有帮助的错误消息。即有以下信息: TypeError: 'float' object has no attribute ' getitem '
如果有人能告诉我如何解决这个问题,那就太好了。
解决方案
对于替代解决方案,您还可以在 python 中为您的函数使用列表理解:
def get_filtered_data(code, d1, d2):
indices = [i for i, s in enumerate(code) if 'correct' in s]
d1_ = [d1[index] for index in indices]
d2_ = [d2[index] for index in indices]
return [len(indices), d1_, d2_]
udf_get_filtered_data = udf(get_filtered_data, ArrayType(StringType()))
df = df.withColumn('filtered_data', udf_get_filtered_data('code', 'd1', 'd2'))
df.show() 返回以下内容
+------+--------------------+----------------+----------------+--------------------+
|number| code| d1| d2| filtered_data|
+------+--------------------+----------------+----------------+--------------------+
| 4|[correct, correct...|[33, 42, 35, 76]|[12, 35, 15, 16]|[3, [33, 42, 76],...|
| 2| [correct, wrong]| [47, 43]| [13, 17]| [1, [47], [13]]|
+------+--------------------+----------------+----------------+--------------------+
顺便说一句,如果你使用
dataFiltered.append([d1[i],d2[i]])
它不会给您指定的所需结果([33, 42, 76], [12, 35, 16])
。相反,它会给你([33,12], [42,35], [76,16])
上面的这个答案为您提供了问题中提到的单独列表中d1
的正确结果。d2
推荐阅读
- scala - 如何在 Scala 中读取方括号内的类型?
- php - laravel mime 验证在验证 pgf 时工作
- javascript - 执行动态脚本后执行代码
- flask - 在 IIS 中为烧瓶应用程序设置代理标头
- azure - 如何从 PowerShell 创建 Azure Automation Runbook 的自动化计划以在 Hybrid Worker 上运行?
- c# - “动态调度”在 .Net Core 3 和 .Net 4.7.2 中的工作方式是否不同?
- javascript - 使用 CloudFront 与 S3TA 的 PUT/POST 请求
- python - PySpark - 将单元素数组/列表转换为字符串
- r - 如何平均 7 年的数据
- python - 使用相同的索引形成子列表