有没有一种方法可以将用户的IP递归分组?

时间:2019-08-20 05:26:39

标签: pandas pyspark

我想用用户的IP(或其他)对用户进行分组。 如下面的示例所示,当给出IP(data)/ user_id表时,请使用第一个数据点(data = 1,users =(a,b,c))从user_id开始。然后收集那些用户使用的其他数据值(用户=(a,b,c),used_data =(2,4,5))。一直进行到发现所有以此方式链接的用户和数据为止。

示例数据(CSV,我将IP替换为随机数据,以便于阅读)

data,user_id
1,a
1,b
1,c
2,a
2,e
3,d
3,h
4,a
5,b
5,f
5,g
6,h
6,i

简而言之,我想收集至少使用一次相同数据的用户。

期望的CSV输出,

group,data,user_id
1,[1,2,4,5],[a,b,c,e,f,g]
2,[3,6],[d,h,i]

2 个答案:

答案 0 :(得分:0)

我认为通过一些辅助功能,在大熊猫中做到这一点会更容易。我已将您的csv粘贴到一个文件中,以弄清楚data变量包含的内容。我已经用索引手动绕过了标头,这取决于您自动执行并删除索引,以及在需要时将最终结果格式化为csv。此解决方案不是显式递归的,但也不是很浪费。

with open('test.csv') as infile:
    data = [l.strip().split(',') for l in infile.readlines()]

def extract_group(data):
    # Start with one entry
    ip, user = data[0]
    ips = {ip}
    users = {user}
    ungrouped = data[1:]
    old_ungrouped_count = 0
    # Go through the remaining data until no related entries are found
    while len(ungrouped) != old_ungrouped_count:
        old_ungrouped_count = len(ungrouped)
        for ip, user in ungrouped[:]:
            if ip in ips or user in users:
                ips.add(ip)
                users.add(user)
                ungrouped.remove([ip, user])
    return (users, ips, ungrouped)

users, ips, ungrouped = extract_group(data[1:])
groups = [(sorted(ips), sorted(users))]
while ungrouped:
    users, ips, ungrouped = extract_group(ungrouped)
    groups.append((sorted(ips), sorted(users)))

for group in groups:
    print(group)

(['1', '2', '4', '5'], ['a', 'b', 'c', 'e', 'f', 'g'])
(['3', '6'], ['d', 'h', 'i'])

答案 1 :(得分:0)

您可以使用pandas.DataFrame.groupby方法,也可以找到文档here。如果需要,可以使用SQL查询来实现,可以使用group_concat()或它的替代方法。要进一步阅读,请查看this帖子。

代码

from io import StringIO
import pandas as pd

raw_data = """data,user_id
1,a
1,b
1,c
2,a
2,e
3,d
3,h
4,a
5,b
5,f
5,g
6,h
6,i"""


df = pd.read_csv(StringIO(raw_data), sep=',')
grouped_df = df.groupby(['data']).apply(lambda x: ','.join(x.user_id))

输出

data
1    a,b,c
2      a,e
3      d,h
4        a
5    b,f,g
6      h,i
dtype: object