Python 在Pyspark中查找每个id的模式值
我有一个约17亿行的pyspark数据帧,模式如下:Python 在Pyspark中查找每个id的模式值,python,dataframe,pyspark,aggregate,Python,Dataframe,Pyspark,Aggregate,我有一个约17亿行的pyspark数据帧,模式如下: INPUT SCHEMA id ip datetime 我试图找到每个id的模式ip 我目前有一个函数,我可以在其中创建一个单独的 INT TABLE id ip number_of_records 然后将其过滤为模态ip 这似乎是难以置信的缓慢和庞大,什么是一个更有效的方式来获得每个ip模式ip Proposed Output Schema id modal_ip 谢谢大家 根据我的评论,这里有一个解决方案,它演示了如何从技术
INPUT SCHEMA
id
ip
datetime
我试图找到每个id的模式ip
我目前有一个函数,我可以在其中创建一个单独的
INT TABLE
id
ip
number_of_records
然后将其过滤为模态ip
这似乎是难以置信的缓慢和庞大,什么是一个更有效的方式来获得每个ip模式ip
Proposed Output Schema
id
modal_ip
谢谢大家 根据我的评论,这里有一个解决方案,它演示了如何从技术上通过两种数据传递实现这一点——一种是计数,另一种是减少并找到(多种)模式。我已经用RDDAPI实现了第二部分——转换为DataFrame API的工作留给读者;)(tbh我不知道是否有可能对多个输出行进行自定义聚合,如下图所示): 这种方法的一个小警告:因为我在内存中聚合了重复模式,所以如果您有许多不同的IP,对于单个ID具有相同的计数,那么就有可能出现OOM问题。对于这个特定的应用程序,我认为这是非常不可能的(例如,一个用户可能不会有100万个不同的IP,所有IP都有一个事件)
但我倾向于同意@absolutelycrasted,最简单的解决方案可能是您已经拥有的解决方案,即使它有额外的数据传递。但是您可能应该避免进行
排序
/排名
,如果可能,只需在窗口中查找最大计数。您所说的“模式ip”是什么意思?我认为这正是您想要的:@彻底破坏了每个id上与之关联的记录最多的ip地址。即,如果该id上有3条记录的ip1和5条记录的ip2,则选择ip2@timchap这基本上就是我所拥有的,我一直在寻找一个更优雅/更快的解决方案,它不需要太多繁重的工作,如果有多种模式呢?
from pyspark.sql import types
import pandas as pd
from pyspark.sql.functions import pandas_udf
from pyspark.sql.functions import PandasUDFType
# Example data
data = [
(0 ,'12.2.25.68'),
(0 ,'12.2.25.68'),
(0 ,'12.2.25.43'),
(1 ,'62.251.0.149'), # This ID has two modes
(1 ,'62.251.0.140'),
]
schema = types.StructType([
types.StructField('id', types.IntegerType()),
types.StructField('ip', types.StringType()),
])
df = spark.createDataFrame(data, schema)
# Count id/ip pairs
df = df.groupBy('id', 'ip').count()
def find_modes(a, b):
"""
Reducing function to find modes (can return multiple).
a and b are lists of Row
"""
if a[0]['count'] > b[0]['count']:
return a
if a[0]['count'] < b[0]['count']:
return b
return a + b
result = (
df.rdd
.map(lambda row: (row['id'], [row]))
.reduceByKey(find_modes)
.collectAsMap()
)
{0: [Row(id=0, ip='12.2.25.68', count=2)],
1: [Row(id=1, ip='62.251.0.149', count=1),
Row(id=1, ip='62.251.0.140', count=1)]}