假设我有一个数据帧,其中一个列包含一个如下所示的修改后的运行序列号:(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()非常气馁,所以还有更好的方法吗?
很抱歉,我没有说清楚,缺少一些随机条目,所以形状并不完全反映我尝试恢复的原始未修改序列。
所以它更像是来自原始序列:
[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 ...]
答案 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添加到模块列即可。我想这会更快。
注意:这回答了最初提出的问题,但没有考虑到丢失条目的可能性。