我有一个包含2列的数据框:类(0/1)和时间(整数)。我需要添加第三列,这将是获得第1类行的剩余时间。
df = pd.DataFrame([
[1,101], [1,104],
[0,107], [0,110], [0,123],
[1,156],
[0,167]],
columns=['class', 'time'])
diff
应该为0。diff
应该是类别为0的第一行的time
和time
之间的差。我可以在Lambda函数中对其进行计算:
df['diff'] = df.apply(lambda x: df[ (df['time'] >= x[1]) & (df['class']==0)]['time'].iloc[0] - x[1], axis=1)
每行都运行表达式df[ (df['time'] >= x[1]) & (df['class']==0)]
,以获取具有类0的下一行。我认为对于大数据框而言,效率不高。
什么是更有效的计算方法?
答案 0 :(得分:4)
与@Datanovice没什么不同。
使用where
到NaN
的时间df['class'] == 1
,然后使用bfill
获得第一个df['class'] == 0
值。该级数获得正确的“时间”来减去,而与类无关,因此我们可以进行常规的相减。
df['Diff'] = df['time'].where(df['class'].eq(0)).bfill() - df['time']
class time Diff
0 1 101 6.0
1 1 104 3.0
2 0 107 0.0
3 0 110 0.0
4 0 123 0.0
5 1 156 11.0
6 0 167 0.0
第一步创建的系列是:
df['time'].where(df['class'].eq(0)).bfill()
#0 107.0
#1 107.0
#2 107.0
#3 110.0
#4 123.0
#5 167.0
#6 167.0
#Name: time, dtype: float64
答案 1 :(得分:2)
IIUC,您可以链接布尔表达式以向量化它。
首先,我们在每1
组中找到第一个0
t = df[df['class'].ne(df['class'].shift()) & df['class'].eq(0)]['time']
print(t)
2 107
6 167
Name: time, dtype: int64
#then we assign a column and back fill it.
df = df.assign(Diff = t).bfill()
最后是有条件地求和并计算0 Diff
值。
df['Diff'] = np.where(df['class'].eq(1),df['Diff'] - df['time'],0)
print(df)
class time Diff
0 1 101 6.0
1 1 104 3.0
2 0 107 0.0
3 0 110 0.0
4 0 123 0.0
5 1 156 11.0
6 0 167 0.0