使用python pandas,如何恢复已修改的运行序列号?

时间:2015-06-10 06:09:53

标签: python pandas

假设我有一个数据帧,其中一个列包含一个如下所示的修改后的运行序列号:(mod by 8) [0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3 ......]

我想要恢复" un-modded"序列 [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 ......]

最好的方法是什么?

我能想到的是使用df.iterrows()检查不连续性以增加" base"值。但是因为.iterrows()非常气馁,所以还有更好的方法吗?

编辑1:

很抱歉,我没有说清楚,缺少一些随机条目,所以形状并不完全反映我尝试恢复的原始未修改序列。

所以它更像是来自原始序列:

[0,2,3,5,6,1,2,3,5,6,7,0,1,2,3 ...]

恢复:

[0,2,3,5,6,9,10,11,13,14,15,16,17,18,19 ...]

3 个答案:

答案 0 :(得分:2)

def unmod_series(my_values,mod_value=8):
    i = 0 
    for first,second in zip(my_values,my_values[1:]):
        yield first + i
        if first > second: i += mod_value
    yield second+i


print list(unmod_series([0, 2, 3, 5, 6, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3],mod_value=8))         

#result is  [0, 2, 3, 5, 6, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19]

我想你会做你想要的......但我认为这基本上与iterrows相同......我猜你正在寻找一种矢量化的方式来做到这一点......我怀疑你会找到一个

答案 1 :(得分:2)

以下是如何使用numpy执行此操作:

composer update

当阵列很小时,性能差异很小, 所以如果@Beasley的回答不那么令人困惑,那就用它吧。

<强>更新

当mod_value很大(例如65536)时,存在显着的性能差异:

import numpy as np


def unmod_array(arr, mod_value=8):
    # when last number is larger or equal to current number, it's a new cycle
    index = np.argwhere(arr[:-1] >= arr[1:]).reshape(-1) + 1
    cycles = np.split(arr, index)
    return np.concatenate(list(arr + i * mod_value for i, arr in enumerate(cycles)))


arr = np.array([0, 2, 3, 5, 6, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3])
print unmod_array(arr)

# result is [ 0  2  3  5  6  9 10 11 13 14 15 16 17 18 19]

答案 2 :(得分:0)

一种可能的解决方案是定义一个生成缺失碱基序列的生成器,从该序列创建Series,然后将其添加到模块列。第一次尝试:

def pieces_of_eight(N):
    for i in range(N // 8):
        for j in range(8):
            yield i
    for j in range(N % 8):
            yield i+1

您可以通过以下方式创建所需的Series

s = Series(pieces_of_eight(len(dataframe)))

然后将其添加到模块化列中。

但是,许多数据集的数字索引从零开始,每行增加一个。如果此列的名称为N,则只需将N // 8添加到模块列即可。我想这会更快。

注意:这回答了最初提出的问题,但没有考虑到丢失条目的可能性。