Pandas:计算当前列值与最接近列值之间的差值,具体取决于它是否满足不同列的标准

时间:2017-12-06 17:39:20

标签: python pandas dataframe

这个问题是这个问题的延伸:Pandas: Calculating value of difference between current column value and next column value depending if it meets criteria at a different column

最初,我想知道每个位置与foobar列中具有相反值的下一个位置之间的差异。

这是一个数据框:

pd.DataFrame.from_items([('A', [10, 'foo']), ('B', [440, 'foo']), ('C', [790, 'bar']), ('D', [800, 'bar']), ('E', [7000, 'foo']), ('F', [14000, 'bar']), ('G', [27000, 'bar'])], orient='index', columns=['position', 'foobar'])

看起来像这样:

    position foobar
A   10       foo
B   440      foo
C   790      bar
D   800      bar
E   7000     foo
F   14000    bar
G   27000    bar

Jezrael提供了一个很好的答案,可以找到每个位置与foobar列中具有相反值的下一个位置之间的差异,从而产生输出:

    position foobar length
A   10       foo     780
B   440      foo     350
C   790      bar     6210
D   800      bar     6200
E   7000     foo     7000
F   14000    bar     NaN
G   27000    bar     NaN

然而,我现在想做的是向前和向后看。所以foo并且应该根据位置查找最近的bar,而不是最近的向前看(在列下方)。所以输出实际上应该是这样的:

    position foobar length
A   10       foo     780
B   440      foo     350
C   790      bar     350
D   800      bar     360
E   7000     foo     6200
F   14000    bar     7000
G   27000    bar     20000

正如您所看到的那样,现在我们正在改变几个长度,因为我们正在向上和向下看foobar柱。我承认不知道如何去做这件事。

1 个答案:

答案 0 :(得分:1)

一种方法是将先前的答案应用于反向排序的数据帧,然后合并结果。

# do solution from previous answer
print(df)

    position    foobar  difference
A   10          foo     780.0
B   440         foo     350.0
C   790         bar     6210.0
D   800         bar     6200.0
E   7000        foo     7000.0
F   14000       bar     NaN
G   27000       bar     NaN

# do the same thing on the reverse sorted df
df2 = df.sort_values(by=['position'], ascending=False)
a2 = df2['foobar'].ne(df2['foobar'].shift()).cumsum()
b2 = df2.groupby(a2)['position'].first()
df2['difference'] = a2.add(1).map(b2) - df2['position']
df2['difference'] *= -1
df2 = df2.sort_values(by='position')

print(df2)

   position foobar  difference
A        10    foo         NaN
B       440    foo         NaN
C       790    bar       350.0
D       800    bar       360.0
E      7000    foo      6200.0
F     14000    bar      7000.0
G     27000    bar     20000.0

# combine the two results
df['difference'] = pd.concat([df['difference'], df2['difference']], axis=1).min(1)

print(df)

   position foobar  difference
A        10    foo       780.0
B       440    foo       350.0
C       790    bar       350.0
D       800    bar       360.0
E      7000    foo      6200.0
F     14000    bar      7000.0
G     27000    bar     20000.0