我试图找到一种方法来做一个pandas框架上的python特殊类型的排序:serpentine排序。
下面是对serpentine sorting的简要描述:
当每个边界都被越过以获得更高级别的排序变量时,Serbian排序会颠倒排序顺序,从而有助于确保相邻记录在尽可能多的排序变量方面是相似的。
下面是一个使用三个变量的蛇形排序的示例,每个变量有三个类别(低、中、高)。在变量1的类别中对变量2进行排序时,排序顺序是相反的,在变量2的类别中对变量3进行排序时,排序顺序又是相反的,这样相邻的记录对于所有三个变量都是相似的。
An example of serpentine sorting
当我能够在SAS中工作时,我使用SAS程序(Proc Survey Select)来进行蛇形排序:
proc surveyselect data=&outfile sort=serp method=seqrate=1;
/* Grouping variables*/
strata &class;
/* Sort Varaibles */
control &sortvar;
run;
字符串
R包中还有一个实用程序可以执行蛇形排序:
https://rdrr.io/github/adamMaier/samplingTools/man/serpentine.html的
有没有人知道在python中使用Pandas的相应方法?
这是我最好的尝试。它可以工作,但它在几个变量之后就崩溃了。我永远无法使用上面的其他方法(例如PROC SURVEY SELECT)来匹配输出。
def serpentine_sort(testframe, classvar , isortvar):
newframe=pandas.DataFrame(testframe)
#create a list of true for each element in the list.
#These will specify that
ascenlist = [True for x in isortvar]
# Perform an initial sort where we first sort by the class, and then the sort variables
# in ascending order within the class
newframe = newframe.sort_values(classvar, ascending=True) \
.groupby(classvar, sort=True) \
.apply(lambda x: x.sort_values(isortvar, ascending=ascenlist)) \
.reset_index(drop=True).copy(deep=True)
##### SERPENTINE SORT THE DATA ONE COLUMN AT A TIME #####
##### ============================================== #####
##### Create a sort variable that is a cumulative count within #####
##### each group in the preceding variable. Use modulus division #####
##### to reverse the count. If the count from the prior groping #####
##### variable is 0, sort ascending, if the not, sort descending #####
grouplist = classvar
for i in range(1, len(isortvar)):
print ("Iteration: " , i )
ranklist=[]
ranklist.append(classvar[0])
ranklist.append(isortvar[i-1])
grouplist.append(isortvar[i-1])
print (ranklist)
print (grouplist)
# Count the groups within the prior column within the class
newframe["counter"] = newframe.groupby([isortvar[i-1]]).ngroup()
newframe["serpvar"] = newframe.loc[ newframe["counter"] % 2 == 0 ].groupby(ranklist)[isortvar[i-1]].cumcount(ascending=True ) + 1
newframe["t"] = newframe.loc[ newframe["counter"] % 2 != 0 ].groupby(ranklist)[isortvar[i-1]].cumcount(ascending=False) + 1
newframe.loc[ newframe["serpvar"].isna() , "serpvar" ] = newframe["t"]
#print ("")
#print ("Pre sorted")
#print ("==========")
#print ("")
#print (newframe)
newframe = newframe.groupby(grouplist, sort=False) \
.apply(lambda x: x.sort_values("serpvar", ascending=[True])) \
.reset_index(drop=True).copy(deep=True)
return newframe
nscg=serpentine_sort(testframe=df, classvar=["BTHRGN"], isortvar=["AGEGRP", "WAPRI", "PRMBR"])
型
注意:classvar参数是一个分组变量。这里我想在组内排序。isortvar参数是我的排序变量的列表。
任何帮助都将受到真诚的感谢。
1条答案
按热度按时间kyvafyod1#
假设此示例输入与您的输入类似:
字符串
你可以先按正常顺序排序,然后计算每个重复值的秩(通过self +较低权重的列的组),并反转奇数值,最后在奇数值乘以-1后再次排序:
型
输出量:
型
中间体:
型