Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Pyspark中查找每个id的模式值_Python_Dataframe_Pyspark_Aggregate - Fatal编程技术网

Python 在Pyspark中查找每个id的模式值

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 谢谢大家 根据我的评论,这里有一个解决方案,它演示了如何从技术

我有一个约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

谢谢大家

根据我的评论,这里有一个解决方案,它演示了如何从技术上通过两种数据传递实现这一点——一种是计数,另一种是减少并找到(多种)模式。我已经用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)]}