因此,我昨天开始提出一个问题:基于同一行中的值以熊猫为单位进行多次分配,我想知道如何对一行数据进行排名并将排名分配给同一行中的不同列。我从这里开始遵循Ed Chum的建议,弄清楚了如何做到这一点:如何一次将函数应用于pandas数据框中的多个列。
它确实有效,但是后来我注意到我在创建过程中创建了不正确的列。而且,一旦我修复了该错误,它便不再起作用。
因此,我尝试在一个玩具示例上重新创建该问题,并且在玩具示例上也无法正常工作。有人可以指出我的错误,这是代码(python 3):
import pandas as pd
import numpy as np
import scipy
df = pd.DataFrame(data={'a':[1,2,3],'b':[2,1,3],'c':[3,1,2],
'rank_a':[np.nan]*3,'rank_b':[np.nan]*3,'rank_c':[np.nan]*3})
def apply_rank(row):
vals = [row['a'],row['b'],row['c']]
ranked = scipy.stats.rankdata(vals)
d = len(vals)+1
ranked = [rank/d for rank in ranked]
rank_cols = [col for col in row.index if col.startswith("rank_")]
print("ranked: "+str(ranked))
for idx,rank_col in enumerate(rank_cols):
print("Before: "+str(row[rank_col]))
row[rank_col] = ranked[idx]
print("After: "+str(row[rank_col]))
然后运行:df.apply(lambda row: apply_rank(row),axis=1)
,以确保分配正确完成。
然后运行:df
查看未分配任何内容.. facepalm
您可以返回Series
带有索引的新列的值:
def apply_rank(row):
vals = [row['a'],row['b'],row['c']]
ranked = scipy.stats.rankdata(vals)
d = len(vals)+1
ranked = [rank/d for rank in ranked]
rank_cols = [col for col in row.index if col.startswith("rank_")]
return pd.Series(ranked, index=rank_cols)
df = df.apply(lambda row: apply_rank(row),axis=1)
print (df)
rank_a rank_b rank_c
0 0.250 0.500 0.750
1 0.750 0.375 0.375
2 0.625 0.625 0.250
编辑:如果之前可能存在新列,则将数据追加到它们并返回row
:
def apply_rank(row):
vals = [row['a'],row['b'],row['c']]
ranked = scipy.stats.rankdata(vals)
d = len(vals)+1
ranked = [rank/d for rank in ranked]
rank_cols = [col for col in row.index if col.startswith("rank_")]
row.loc[rank_cols] = ranked
return row
df = df.apply(apply_rank,axis=1)
print (df)
a b c rank_a rank_b rank_c
0 1.0 2.0 3.0 0.250 0.500 0.750
1 2.0 1.0 1.0 0.750 0.375 0.375
2 3.0 3.0 2.0 0.625 0.625 0.250
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句