Python 在panda数据帧中获得n个最小的行
我的数据框如下所示:Python 在panda数据帧中获得n个最小的行,python,pandas,dataframe,Python,Pandas,Dataframe,我的数据框如下所示: A B C D date 2015-01-01 1 1 2 3 2015-01-02 1 2 3 3 2015-01-03 1 2 1 3 2015-01-04 3 2 1 1 2015-01-05 3 2 2 1 2015-01-06 1 1 2 3 2015-01-07 1 2 3 3 2015-01-08 1 2 1 3 2015-01-0
A B C D
date
2015-01-01 1 1 2 3
2015-01-02 1 2 3 3
2015-01-03 1 2 1 3
2015-01-04 3 2 1 1
2015-01-05 3 2 2 1
2015-01-06 1 1 2 3
2015-01-07 1 2 3 3
2015-01-08 1 2 1 3
2015-01-09 3 2 1 1
2015-01-10 3 2 2 1
2015-01-11 3 2 2 1
基本规则:我想为每行确定2个最小值,并将这些值设置为1。其他值应设置为0
其他规则:
1 1 1 1 should be 1 1 1 1
1 2 2 2 should be 1 1 1 1
1 2 2 3 should be 1 1 1 0
1 2 3 4 should be 1 1 0 0
我希望您能够遵循规则,对于开始时的数据帧,结果应该是
date A B C D
2015-01-01 1 1 0 0
2015-01-02 1 1 0 0
2015-01-03 1 0 1 0
2015-01-04 0 0 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 0 0
2015-01-07 1 1 0 0
2015-01-08 1 0 1 0
2015-01-09 0 0 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
编辑
“也许你想用class='first'方法排名,我想这是可行的–EdChum”
数据帧的结果:
A B C D
date
2015-01-01 1 2 3 4
2015-01-02 1 2 3 4
2015-01-03 1 3 2 4
2015-01-04 4 3 1 2
2015-01-05 4 2 3 1
2015-01-06 1 2 3 4
2015-01-07 1 2 3 4
2015-01-08 1 3 2 4
2015-01-09 4 3 1 2
2015-01-10 4 2 3 1
2015-01-11 4 2 3 1
我想这正是你想要的:
In [3]:
mask = df.rank(method='dense', axis=1) <= 2
df[mask] = 1
df[~mask] = 0
df
Out[3]:
A B C D
date
2015-01-01 1 1 1 0
2015-01-02 1 1 0 0
2015-01-03 1 1 1 0
2015-01-04 0 1 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 1 0
2015-01-07 1 1 0 0
2015-01-08 1 1 1 0
2015-01-09 0 1 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
[3]中的
mask=df.rank(method='densite',axis=1)我想这就是你想要的:
In [3]:
mask = df.rank(method='dense', axis=1) <= 2
df[mask] = 1
df[~mask] = 0
df
Out[3]:
A B C D
date
2015-01-01 1 1 1 0
2015-01-02 1 1 0 0
2015-01-03 1 1 1 0
2015-01-04 0 1 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 1 0
2015-01-07 1 1 0 0
2015-01-08 1 1 1 0
2015-01-09 0 1 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
[3]中的
mask=df.rank(method='dense',axis=1)如果您想扩展超过4列,也许您可以尝试以下方法,前面解决方案中的mask思想也是我实现它的方式,但是您可以指定您想要两个最小的值:
mask = df.apply(lambda x: x.isin(x.nsmallest(2)), axis=1)
df[mask] = 1
df[~mask] = 0
df
A B C D
2015-01-01 1 1 0 0
2015-01-02 1 1 0 0
2015-01-03 1 0 1 0
2015-01-04 0 0 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 0 0
2015-01-07 1 1 0 0
2015-01-08 1 0 1 0
2015-01-09 0 0 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
我担心此解决方案在更大数据集上的性能,但它应该会为您找到您想要的答案如果您想扩展超过4列,也许您可以尝试以下方法,我也会采用以前解决方案中的掩码思想来实现它,但是,您可以指定需要两个最小的值:
mask = df.apply(lambda x: x.isin(x.nsmallest(2)), axis=1)
df[mask] = 1
df[~mask] = 0
df
A B C D
2015-01-01 1 1 0 0
2015-01-02 1 1 0 0
2015-01-03 1 0 1 0
2015-01-04 0 0 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 0 0
2015-01-07 1 1 0 0
2015-01-08 1 0 1 0
2015-01-09 0 0 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
我担心这个解决方案在更大的数据集上的性能,但它应该能为您找到您想要的答案很好,但是否有可能得到一个更通用的解决方案来处理第n个最低值(在上面的示例中,n=2)并且可以处理超过4列?我意识到这只适用于行中的值总数等于大小除以n
,我认为更通用的解决方案是使用apply
,但它不会被矢量化,因此对于大型DFS来说速度会很慢。值是否始终为整数且从1到4?我认为使用rank
可以实现您想要的功能,请参阅我的editNo,示例是将rank应用于原始数据帧,结果将是1到max=列数(但如果一行中有两个值为requal,则结果会更小).很好,但是有没有可能得到一个更通用的解决方案,可以处理第n个最小值(在上面的示例中,n=2)并且可以处理4列以上的列?我意识到这只适用于行中的值总数等于大小除以n
,一个更通用的解决方案是使用apply
,我想,但它不会被矢量化,因此对于较大的DFS来说速度会很慢。值是否始终是整数,从1到4?我认为使用rank
可以满足您的需要,请参阅我的editNo,示例是将rank应用于原始数据帧,结果将是1到max=列数(但如果一行中有两个值为requal,则该值将更小)。