【问题标题】:Finding the number of observations before a change in a Series occurs (pandas/numpy)在系列发生变化之前查找观察次数(pandas/numpy)
【发布时间】:2017-04-05 01:01:16
【问题描述】:

给定 Series ,我想有效地计算在系列发生变化之前有多少观察值。这是一个简单的例子:

ser = pd.Series([1.2,1.2,1.2,1.2,2,2,2,4,3])

print(ser)

0    1.2
1    1.2
2    1.2
3    1.2
4    2.0
5    2.0
6    2.0
7    4.0
8    3.0

我想对ser 应用一个函数,这将导致:

0    4
1    3
2    2
3    1
4    3
5    2
6    1
7    1
8    1

由于我正在处理大型系列,我更喜欢不涉及循环的快速解决方案。

【问题讨论】:

  • 你试过什么?如果解决方案不涉及循环,您如何扫描和打印输入/输出?
  • 请发布给您带来麻烦的代码。要求其他人为您设计解决方案有点超出我们的明确目的。
  • 我正在寻找比我更快的代码。现在用代码更新问题

标签: python python-3.x pandas numpy series


【解决方案1】:

这是基于this post 的 NumPy 方法 -

def array_cumcount_descending(a):
    idx = np.flatnonzero(a[1:] != a[:-1])+1
    shift_arr = -np.ones(a.size,dtype=int)

    if len(idx)>=1:
        shift_arr[0] = idx[0]
        shift_arr[idx[:-1]] = idx[1:] - idx[:-1] - 1
        shift_arr[idx[-1]] = a.size - idx[-1] - 1    
    else:
        shift_arr[0] = a.size
    return shift_arr.cumsum()

示例运行 -

In [70]: ser
Out[70]: 
0    1.2
1    1.2
2    1.2
3    1.2
4    2.0
5    2.0
6    2.0
7    4.0
8    3.0
dtype: float64

In [71]: array_cumcount_descending(ser.values)
Out[71]: array([4, 3, 2, 1, 3, 2, 1, 1, 1])

【讨论】:

    【解决方案2】:

    您可以将groupbycumcount 一起使用:

    >>> ser.groupby(ser).cumcount(ascending=False)+1
    0    4
    1    3
    2    2
    3    1
    4    3
    5    2
    6    1
    7    1
    8    1
    dtype: int64
    

    根据@DSM 的评论,如果您有多个相同值的块,则上述方法将不起作用,但您可以使用以下方法扩展解决方案:

    >>> ser = pd.Series([1.2, 1.2, 1.2, 1.2, 2, 2, 2, 1.2, 1.2, 1.2, 4, 3])
    >>> ser.groupby((ser != ser.shift()).cumsum()).cumcount(ascending=False)+1
    0     4
    1     3
    2     2
    3     1
    4     3
    5     2
    6     1
    7     3
    8     2
    9     1
    10    1
    11    1
    dtype: int64
    

    【讨论】:

    • IIUC,这只是因为碰巧在 OP 的系列中没有重复的值(我的意思是不连续的),因此对值进行分组与在有变化的地方进行分组相同。
    • 这行得通,谢谢。虽然如果碰巧有一个更快的解决方案可能会很棒。
    • @splinter 没有看到你的代码,无法比较速度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    相关资源
    最近更新 更多