根据两列对熊猫数据帧进行排序,这些列相似,但如果另一列有值,则另一列为 NaN



我有一个合并的 df,它有 2 个实验 ID - experiment_a 和 experiment_b

它们在一般命名法中EXPT_YEAR_NUM但有些有附加组件,没有年份而不是其他值。在此 df 中,experiment_a 中有一个值,experiment_b = NaN,反之亦然。

即:

experiment_a    experiment_b
EXPT_2011_06     NaN
NaN              EXPT_2011_07

如何排序,使 experiment_a 和_b的升序值在一起,而不是在具有所有 NaN 值的情况下_b experiment_a升序,然后在experiment_a具有 NaN 值时以experiment_b升序?

这是我使用sort_values时发生的情况:

df = df.sort_values(['experiment_a', 'experiment_b'])

它显然只是先对_a进行排序,然后再_b。

我相信您需要fillna才能Series,然后按argsort获取排序值的索引,最后按iloc选择-输出是排序列:

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.where性能更好一些,但主要取决于数据:

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]

最新更新