熊猫中基于行的有效计算方法

时间:2020-07-09 16:30:38

标签: python pandas lambda pandas-apply

我有一个包含2列的数据框:类(0/1)和时间(整数)。我需要添加第三列,这将是获得第1类行的剩余时间。

df = pd.DataFrame([
    [1,101], [1,104],
    [0,107], [0,110], [0,123],
    [1,156],
    [0,167]],
  columns=['class', 'time'])
  • 如果一行的类为0; diff应该为0。
  • 如果一行具有1类; diff应该是类别为0的第一行的timetime之间的差。

我可以在Lambda函数中对其进行计算:

df['diff'] = df.apply(lambda x: df[ (df['time'] >= x[1]) & (df['class']==0)]['time'].iloc[0] - x[1], axis=1)

enter image description here

每行都运行表达式df[ (df['time'] >= x[1]) & (df['class']==0)],以获取具有类0的下一行。我认为对于大数据框而言,效率不高。

什么是更有效的计算方法?

2 个答案:

答案 0 :(得分:4)

与@Datanovice没什么不同。

使用whereNaN的时间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