从大型数据集中提取唯一数据

时间:2017-05-10 10:20:44

标签: python python-2.7 csv pandas scikit-learn

我有一个非常大的CSV数据集(900M记录),它由以下格式组成:

URL | IP | ActivityId

示例数据:

http://google.com/ | 127.0.0.1 | 2
http://google.com/ | 12.3.3.1 | 1

对于这种格式,我希望获得每个网址的所有唯一活动,这些活动不会出现在其他网址中。

例如,让我们再添加一个样本到我上面提供的数据

http://yahoo.com/ | 123.4.5.1 | 2

现在,ActivityId 2完全被排除在外,因为它属于两个网址:谷歌和雅虎。所以我想要的是找到属于单个URL的所有活动,并且我希望知道它们所属的URL。

我试图做的事情:

创建字典

URL => set(activity1, activity2, ... , activityN)

(这部分很慢,在这里回答Parse a very large CSV dataset

使用这个字典,我将每个条目相互比较,找到了集合之间的差异,并用差异结果更新了相应的集合。

如何使用熊猫完成我想要的东西?

3 个答案:

答案 0 :(得分:3)

nunique的另一个解决方案:

df.groupby('ActivityId')['URL'].filter(lambda x: x.nunique() == 1)

使用transformboolean indexing加快解决方案:

df[df.groupby('ActivityId')['URL'].transform('nunique') == 1]

答案 1 :(得分:2)

In [21]: df.groupby('ActivityId')['URL'].filter(lambda x: len(x.unique()) == 1)
Out[21]:
1    http://google.com/
Name: URL, dtype: object

答案 2 :(得分:0)

如果您还想知道属于单个网址的ActivityID,可以使用以下解决方案:

想象一下,你有以下数据集:

    URL                 IP          ActivityId
0   http://google.com/  127.0.0.1   2
1   http://google.com/  12.3.3.1    1
2   http://yahoo.com/   123.4.5.1   2
3   http://yahoo.com/   123.4.5.1   5

你可以这样做:

In[1]:groups = df.groupby('ActivityId')['URL']
      for name, group in groups:
          if group.size == 1:
              print (name,group.values[0])

Out[2]:1 http://google.com/ 
       5 http://yahoo.com/ 

同时使用:

df.groupby('ActivityId')['URL'].filter(lambda x: len(x.unique()) == 1)

收率:

1    http://google.com/ 
3     http://yahoo.com/ 
Name: URL, dtype: object