Python 基于两个相似的列对数据帧进行排序,但如果另一列具有值,则其中一列将为NaN

Python 基于两个相似的列对数据帧进行排序,但如果另一列具有值,则其中一列将为NaN,python,pandas,Python,Pandas,我有一个合并的df,它有两个实验ID——实验a和实验b 它们在通用术语EXPT_YEAR_NUM中,但有些有附加值,当然没有年份,而没有其他值。在这个df中,实验_a中有一个值,实验_b=NaN,反之亦然 即: 我如何排序,使实验a和b的升序值在一起,而不是在实验a上升序,实验b有所有NaN值,然后在实验a有NaN值时,与实验b一起升序 这就是我使用sort_值时发生的情况: df = df.sort_values(['experiment_a', 'experiment_b']) 很明显,它

我有一个合并的df,它有两个实验ID——实验a和实验b

它们在通用术语EXPT_YEAR_NUM中,但有些有附加值,当然没有年份,而没有其他值。在这个df中,实验_a中有一个值,实验_b=NaN,反之亦然

即:

我如何排序,使实验a和b的升序值在一起,而不是在实验a上升序,实验b有所有NaN值,然后在实验a有NaN值时,与实验b一起升序

这就是我使用sort_值时发生的情况:

df = df.sort_values(['experiment_a', 'experiment_b'])
很明显,它只是先排序a,然后再排序b

我相信您需要使用
系列
,然后按获取排序值的索引,最后按选择-输出为排序列:

print (df)
   experiment_a  experiment_b
0  EXPT_2011_06           NaN
1  EXPT_2010_06           NaN
2           NaN  EXPT_2011_07

df = df.iloc[df['experiment_a'].fillna(df['experiment_b']).argsort()]
print (df)
   experiment_a  experiment_b
1  EXPT_2010_06           NaN
0  EXPT_2011_06           NaN
2           NaN  EXPT_2011_07
详细信息

print (df['experiment_a'].fillna(df['experiment_b']))
0    EXPT_2011_06
1    EXPT_2010_06
2    EXPT_2011_07
Name: experiment_a, dtype: object

print (df['experiment_a'].fillna(df['experiment_b']).argsort())
0    1
1    0
2    2
Name: experiment_a, dtype: int64
我用
np测试了更多的解决方案。其中
的性能稍好一些,但主要取决于数据:

print (df)
   experiment_a  experiment_b
0  EXPT_2011_03           NaN
1           NaN  EXPT_2009_08
2           NaN  EXPT_2010_06
3  EXPT_2010_07           NaN
4           NaN  EXPT_2011_07

#[500000 rows x 2 columns]
df = pd.concat([df] * 100000, ignore_index=True)

In [41]: %timeit (df.iloc[(np.where(df['experiment_a'].isnull(), df['experiment_b'], df['experiment_a'])).argsort()])
1 loop, best of 3: 318 ms per loop

In [42]: %timeit (df.iloc[df['experiment_a'].fillna(df['experiment_b']).argsort()])
1 loop, best of 3: 335 ms per loop

In [43]: %timeit (df.iloc[df['experiment_a'].combine_first(df['experiment_b']).argsort()])
1 loop, best of 3: 333 ms per loop

In [44]: %timeit (df.iloc[df.experiment_a.where(df.experiment_a.notnull(), df.experiment_b).argsort()])
1 loop, best of 3: 342 ms per loop

首先构造一个单柱:

key = df.experiment_a.where(df.experiment_a.notnull(), df.experiment_b)
然后索引:

idx = key.argsort()
最后:

df.iloc[idx]

使用
where
构造一个列?您可以为具有预期输出的样本添加更多值吗?
df.iloc[idx]