用文字来说:
我有一个数据框,其中包含每个 Userid
多天的一天值。我想将某些人的所有数据移动 1 个周期,以便他们的第一列中的第一个值是 nan,然后所有内容都循环偏移,最后一个值被截断或丢失空间和时间,以更快者为准。
我目前正在做的事情很慢,因为我最终遍历了我感兴趣的人的所有行。我想知道是否没有我没有想到的更快的解决方案。
在代码中:
给定这个数据集:
df = pd.DataFrame([['person1','3/1/2014',1,2,3,4,5,6,7,8,9],
['person1','3/2/2014',4,1,4,1,4,1,4,1,4],
['person2','3/1/2014',2,3,4,5,6,7,8,9,9],
['person2','3/2/2014',6,5,4,3,2,1,0,-1,-15]],columns =
['Userid','Date','T1','T2','T3','T4','T5','T6','T7','T8','T9'])
我目前使用以下代码来移动某些 id 的值:
def shift_by_1(df_):
next_seed_value = [np.nan]
L=[]
for i,row in df.iterrows():
newrow_plus = next_seed_value+row.values.tolist()
next_seed_value = [newrow_plus[-1]]
newrow = newrow_plus[:-1]
L.append(newrow)
return pd.DataFrame(L)
LL = []
for xx in ids_to_be_shifted:
LL.append(shift_by_15(df[df['id']==xx]))
newdf = pd.concat(LL)
它实现了以下目标:
newdf == pd.DataFrame([['person1','3/1/2014',np.nan,1,2,3,4,5,6,7,8],
['person1','3/2/2014',9,4,1,4,1,4,1,4,1],
['person2','3/1/2014',np.nan,2,3,4,5,6,7,8,9],
['person2','3/2/2014',9,6,5,4,3,2,1,0,-1]],columns =
['Userid','Date','T1','T2','T3','T4','T5','T6','T7','T8','T9'])
问题是 shift_by_1
速度很慢。我觉得必须有一种更快的方法,也许通过 group-by + 巧妙地使用 lambda 和类似 np.ravel() 及其相反的东西?
非常感谢任何和所有帮助,提前致谢。
最佳答案
IIUC:
newdf = (df.set_index(['Userid','Date'])
.stack()
.groupby(level=[0])
.shift()
.unstack(level=-1)
.reset_index()
)
输出:
Userid Date T1 T2 T3 T4 T5 T6 T7 T8 T9
0 person1 3/1/2014 NaN 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0
1 person1 3/2/2014 9.0 4.0 1.0 4.0 1.0 4.0 1.0 4.0 1.0
2 person2 3/1/2014 NaN 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
3 person2 3/2/2014 9.0 6.0 5.0 4.0 3.0 2.0 1.0 0.0 -1.0
关于python - 在 pandas 数据框中循环包装值的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57263081/