首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据两个类似的列对熊猫数据进行排序,但如果另一列有一个值,则其中一个将是NaN

根据两个类似的列对熊猫数据进行排序,但如果另一列有一个值,则其中一个将是NaN
EN

Stack Overflow用户
提问于 2018-02-09 11:33:26
回答 2查看 857关注 0票数 3

我有一个合并的df,它有两个实验I experiment_a和experiment_b。

他们是在一般的命名EXPT_YEAR_NUM,但有些有增加的of,没有一年,而不是一些其他的价值。在这个df中,experiment_a中有一个值,experiment_b = NaN,反之亦然。

ie:

代码语言:javascript
复制
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时,会发生这样的情况:

代码语言:javascript
复制
df = df.sort_values(['experiment_a', 'experiment_b'])

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-09 11:43:02

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

代码语言:javascript
复制
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

细节

代码语言:javascript
复制
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可以获得更好的性能,但主要取决于数据:

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2018-02-09 11:43:08

首先构造一个列:

代码语言:javascript
复制
key = df.experiment_a.where(df.experiment_a.notnull(), df.experiment_b)

然后是指数:

代码语言:javascript
复制
idx = key.argsort()

最后:

代码语言:javascript
复制
df.iloc[idx]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48704922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档