熊猫应用功能 - 将每一行与整列进行比较

Posted

技术标签:

【中文标题】熊猫应用功能 - 将每一行与整列进行比较【英文标题】:Pandas apply function - comparing each row to entire column 【发布时间】:2016-03-08 20:24:24 【问题描述】:

第一次发帖;为格式错误道歉。我正在尝试计算给定类别中我的(更大的)数据框中的所有记录,这些记录在该类别中其他记录的设定时间内。

groupby 函数很有意义,但我在定义适当的应用函数时遇到了麻烦。我已经看到使用多个列作为函数输入的示例,以及其他使用 axis=1 来查看单个行的示例,但没有看到使用整个列(查找匹配项)和条目的描述有问题的行(以确定时间范围)。

我还研究了使用 pd.TimeGrouper 按类别和时间对记录进行分组,但这可能会遗漏边缘情况。

最后,按类别拆分可能会使每个组小到足以直接迭代,但如果可能的话,我想学习 Pythonic 方式。

示例代码:

data = ['xfrm':'a', 'time':10, 
        'xfrm':'a', 'time':12, 
        'xfrm':'a', 'time':20,
        'xfrm':'b', 'time':7, 
        'xfrm':'b', 'time':8, 
        'xfrm':'b', 'time':15,
        'xfrm':'c', 'time':2, 
        'xfrm':'c', 'time':8, 
        'xfrm':'c', 'time':15]
df = pd.DataFrame(data)
print df 

对于每条记录,统计同一台转换器在一段时间内(例如 2 秒)的所有记录

answerData = ['xfrm':'a', 'time':10, 'num':2, 
        'xfrm':'a', 'time':12, 'num':2, 
        'xfrm':'a', 'time':20, 'num':1,
        'xfrm':'b', 'time':7, 'num':2, 
        'xfrm':'b', 'time':8, 'num':2, 
        'xfrm':'b', 'time':15, 'num':1,
        'xfrm':'c', 'time':2, 'num':1, 
        'xfrm':'c', 'time':8, 'num':1, 
        'xfrm':'c', 'time':15, 'num':1]
answerDF = pd.DataFrame(answerData)
print answerDF


# Grouping works fine
gb = df.groupby('xfrm')
for name, group in gb:
    print name
    print group

编辑:我认为沿着这些思路可能会起作用,但我不确定引用时间列替换“XXXXXX”的适当方法应该是什么。

def getMatches(x, potentials):
    """Applied to the group of restores attributed to meters associated with a particular transformer. 
    Checks each to see how many in the total set are within the time window. """
    matches = 0
    for time in potentials:
        if abs(timedelta(x - time).seconds) < 1200:
                matches += 1
    return matches

detailRestoreDF.groupby('category')['timestamp'].apply(getMatches,args=(XXXXXX,))

【问题讨论】:

【参考方案1】:

不是很好,但提供了所需的输出:

def func(t):
    res = [0] * len(t.time)
    for i, x in enumerate(t.time):
        for y in t.time:
            if abs(x - y) <= 2:
                res[i] += 1
    t['num'] = res
    return t
print(gb.apply(func))

输出:

   time xfrm  num
0    10    a    2
1    12    a    2
2    20    a    1
3     7    b    2
4     8    b    2
5    15    b    1
6     2    c    1
7     8    c    1
8    15    c    1

不确定我是否了解您在寻找什么。但是您可以访问 apply 函数内的列。例如,这会计算一个组中有多少行的时间小于 12:

>>> gb.apply(lambda x: len(x[x.time < 12]))
xfrm
a    1
b    2
c    2
dtype: int64

或者在开放范围内6 &lt; time &lt; 12

>>> gb.apply(lambda x: len(x[(6 < x.time) & (x.time < 12)]))    xfrm
a    1
b    2
c    1
dtype: int64

【讨论】:

这个功能很有意义 - 您可以使用 apply 将每个元素与固定值进行比较(在您的示例中,x&lt;126&lt;x&lt;12)。对于每个元素,我正在寻找的内容需要与所有其他元素进行比较并返回与接近标准匹配的数字。 添加了一个可以做你想做的事情的版本。 谢谢 - 迭代方法是有效的,但推动了可接受速度的界限。 继续 - 我认为它是 O(n^2),因为它需要将每个值与所有其他值进行比较。我曾希望使用产生更多较小段的分组标准来应用该函数来加快计算速度,但在实践中似乎并非如此。知道这是根本性的误解,还是只是实施的问题?

以上是关于熊猫应用功能 - 将每一行与整列进行比较的主要内容,如果未能解决你的问题,请参考以下文章

如何将每一行熊猫数据帧附加到另一个数据帧的每一行

熊猫:追加行小计的新列

我正在使用熊猫数据框,我需要在不使用循环的情况下将一整列纪元时间戳转换为人类时间

应用字典查找功能来比较熊猫数据框列

熊猫将每小时时间序列重新采样为每小时比例时间序列

比较熊猫数据框中的行值