最初,我想知道每个位置与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柱。我承认不知道如何去做这件事。
答案 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