DataFrame中最大值和第二个最大值之间的差异

时间:2015-07-23 10:09:44

标签: python pandas

我有一个DataFrame我想要将DataFrame中的最大值和第二个最大值之间的差异作为附加到DataFrame的新列作为输出。

例如,数据框看起来像这样(这是一个非常庞大的DataFrame):

 gene_id    Time_1  Time_2  Time_3
a   0.01489251  8.00246 8.164309
b   6.67943235  0.8832114   1.048761

到目前为止,我尝试了以下内容,但它只是采用了标题,

largest = max(df)
second_largest = max(item for item in df if item < largest)

并单独返回标头值。

3 个答案:

答案 0 :(得分:1)

这是我的解决方案:

# Load data
data = {'a': [0.01489251, 8.00246, 8.164309], 'b': [6.67943235, 0.8832114, 1.048761]}
df = pd.DataFrame.from_dict(data, 'index')

诀窍是对值进行线性排序,并使用numpy.argpartition保持前2。 您将绝对值中的2个最大值区分开来。该功能按行方式应用。

def f(x):
    ind = np.argpartition(x.values, -2)[-2:]
    return np.abs(x.iloc[ind[0]] - x.iloc[ind[1]])

df.apply(f, axis=1)

答案 1 :(得分:1)

您可以定义一个func,它接受值,对它们进行排序,对前2个值([:2])进行切片,然后计算差值并返回第二个值(第一个值为NaN)。您apply这个并传递arg axis=1以逐行应用:

In [195]:
def func(x):
    return -x.sort(inplace=False, ascending=False)[:2].diff()[1]

df['diff'] = df.loc[:,'Time_1':].apply(func, axis=1)
df

Out[195]:
  gene_id    Time_1    Time_2    Time_3      diff
0       a  0.014893  8.002460  8.164309  0.161849
1       b  6.679432  0.883211  1.048761  5.630671

答案 2 :(得分:1)

这是一个优雅的解决方案,不涉及排序或定义任何功能。它也完全矢量化,因为它避免使用apply方法。

maxes = df.max(axis=1)
less_than_max = df.where(df.lt(maxes, axis='rows'))
seconds = less_than_max.max(axis=1)
df['diff'] = maxes - seconds