【问题标题】:Exception during groupby pandasgroupby pandas 期间的异常
【发布时间】:2013-09-21 09:36:51
【问题描述】:

我刚开始使用Python For Data Analysis 书学习使用 python 进行网络分析的分析,我对我在做一些 groupby 时遇到的异常感到困惑......这是我的情况。

我有一个 CSV 格式的 NetFlow 数据,已导入到 pandas。数据看起来像:

dt, srcIP, srcPort, dstIP, dstPort, bytes
2013-06-06 00:00:01.123, 123.123.1.1, 12345, 234.234.1.1, 80, 75

我已按如下方式导入和索引数据:

df = pd.read_csv('mycsv.csv')
df.index = pd.to_datetime(full_set.pop('dt'))

我想要的是每个时间段访问我的服务器的唯一 srcIP 计数(我有几天的数据,我希望按日期、小时计算时间段)。我可以通过如下分组和绘图获得整体流量图:

df.groupby([lambda t: t.date(), lambda t: t.hour]).srcIP.nunique().plot()

但是,我想知道总体流量是如何在我的服务器之间分配的。我的直觉是另外按“dstIP”列(只有 5 个唯一值)进行分组,但是当我尝试在 srcIP 上聚合时出现错误。

grouped = df.groupby([lambda t: t.date(), lambda t: t.hour, 'dstIP'])
grouped.sip.nunique()
...
Exception: Reindexing only valid with uniquely valued Index objects

所以,我的具体问题是:我怎样才能避免这个异常,以便创建一个流量在 1 小时内聚合的图,并且每个服务器都有不同的系列。

更一般地说,请让我知道我正在犯什么新错误。 此外,数据没有常规的频率时间戳,我不希望采样数据对您的答案产生任何影响。

编辑 1 这是我的 ipython 会话,与输入完全相同。输出被省略,除了错误中最深的几个调用。

编辑 2 将 pandas 从 0.8.0 升级到 0.12.0 会产生如下所示的更具描述性的异常

import numpy as np
import pandas as pd
import time
import datetime

full_set = pd.read_csv('june.csv', parse_dates=True, index_col=0)
full_set.sort_index(inplace=True)
gp = full_set.groupby(lambda t: (t.date(), t.hour, full_set['dip'][t]))
gp['sip'].nunique()
... 
/usr/local/lib/python2.7/dist-packages/pandas/core/groupby.pyc in _make_labels(self)
   1239             raise Exception('Should not call this method grouping by level')
   1240         else:
-> 1241             labs, uniques = algos.factorize(self.grouper, sort=self.sort)
   1242             uniques = Index(uniques, name=self.name)
   1243             self._labels = labs

/usr/local/lib/python2.7/dist-packages/pandas/core/algorithms.pyc in factorize(values, sort, order, na_sentinel)
    123     table = hash_klass(len(vals))
    124     uniques = vec_klass()
--> 125     labels = table.get_labels(vals, uniques, 0, na_sentinel)
    126 
    127     labels = com._ensure_platform_int(labels)

/usr/local/lib/python2.7/dist-packages/pandas/hashtable.so in pandas.hashtable.PyObjectHashTable.get_labels (pandas/hashtable.c:12229)()

/usr/local/lib/python2.7/dist-packages/pandas/core/generic.pyc in __hash__(self)
     52     def __hash__(self):
     53         raise TypeError('{0!r} objects are mutable, thus they cannot be'
---> 54                               ' hashed'.format(self.__class__.__name__))
     55 
     56     def __unicode__(self):

TypeError: 'TimeSeries' objects are mutable, thus they cannot be hashed

【问题讨论】:

    标签: python python-2.7 group-by pandas time-series


    【解决方案1】:

    所以我不能 100% 确定为什么会引发该异常......但有一些建议:

    您可以使用read_csv 一次性读取数据并按日期时间解析日期时间和索引:

    df = pd.read_csv('mycsv.csv', parse_dates=True, index_col=0)
    

    然后您可以使用返回值元组的 lambda 函数来组成您的组:

    gp = df.groupby( lambda t: ( t.date(), t.hour, df['dstIP'][t] ) )
    

    这个 lambda 函数的输入是索引,我们可以使用这个索引进入外部范围内的数据帧,并在该索引处检索 srcIP 值,从而将其分解到分组中。

    现在我们有了分组,我们可以应用聚合器了:

    gp['srcIP'].nunique()
    

    【讨论】:

    • 奇怪的是,我现在在尝试聚合时得到一个TypeError: unhashable type。尝试显示 gp.groups 时也会引发同样的错误,我认为一旦原始组命令成功,就不应该发生这种错误。
    • 你能发布你执行和输入的确切代码吗?鉴于您在原始帖子中显示的确切输入,我发布的内容有效,我不确定 TypeError 可能来自哪里
    【解决方案2】:

    我最终通过在原始数据框中添加一列新的小时截断日期时间来解决我的问题,如下所示:

    f = lambda i: i.strftime('%Y-%m-%d %H:00:00')
    full_set['hours'] = full_set.index.map(f)
    

    然后我可以groupby('dip') 并循环遍历每个 destIP,创建一个每小时分组的情节...

    for d, g in dipgroup:
        g.groupby('hours').sip.nunique().plot()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      相关资源
      最近更新 更多