我正在寻找一种方法,当列数不明确知道时,可以将多个列相互比较。
具体来说,给定N列,我想创建一个名为'result'
的附加列,其中每行的值为:
1
,如果该行为col(0) > col(1) > col(2) > ... > col(N-1) > col(N)
-1
,如果相反情况成立(col(0) < col(1) < ... < col(N-1) < col(N)
0
,如果以上均不为真
例如,使用以下 Dataframe
df = pd.DataFrame({'col1': [1,2,3,4,5,6,7,8,1],
'col2': [4,3,2,1,0,-1,-2,-3,1],
'col3': [8,6,4,2,0,-2,-4,-6,1]})
col1 col2 col3
0 1 4 8
1 2 3 6
2 3 2 4
3 4 1 2
4 5 0 0
5 6 -1 -2
6 7 -2 -4
7 8 -3 -6
8 1 1 1
我应该得到下面的结果列
col1 col2 col3 result
0 1 4 8 -1
1 2 3 6 -1
2 3 2 4 0
3 4 1 2 0
4 5 0 0 0
5 6 -1 -2 1
6 7 -2 -4 1
7 8 -3 -6 1
8 1 1 1 0
我可以简单地
condition1 = (df['col1'] > df['col2']) & (df['col2'] > df['col3'])
condition2 = (df['col1'] < df['col2']) & (df['col2'] < df['col3'])
df['result'] = np.select([condition1,condition2], [1,-1], 0)
问题是随着列数的增加,这很快变得非常低效。
我尝试过将列转换为列表,获取每个列表的第一个元素,检查它们是降序还是升序(使用我在搜索这个答案时找到的一个函数),然后从中创建一个“结果列表”。
#Checking whether the list given is in Ascending or Descending order
def isOrdered(some_list):
isAscending = True
isDescending = True
for i in range(1,len(some_list)):
if(some_list[i] >= some_list[i-1]):
isDescending = False
elif(some_list[i] <= some_list[i-1]):
isAscending = False
if(isAscending):
return -1
if(isDescending):
return 1
return 0
#Converting the columns to lists and compare the nth elements of each, one at a time
#The columns are guaranteed to be of the same length
col_list = [df[x].to_list() for x in df.columns]
result_list = []
n=0
while n in range(len(col_list[0])):
tmp_lst = []
for idx in range(len(col_list)):
tmp_lst.append(col_list[idx][n])
result_list.append(isOrdered(tmp_lst))
n +=1
df['result'] = result_list
这给我提供了以下DataFrame(它的问题是,如果所有值都相同,它将返回-1而不是0,但只要它准确地告诉我列是Ascending还是notAscending,我就可以接受它)
col1 col2 col3 result
0 1 4 8 -1
1 2 3 6 -1
2 3 2 4 0
3 4 1 2 0
4 5 0 0 0
5 6 -1 -2 1
6 7 -2 -4 1
7 8 -3 -6 1
8 1 1 1 -1
这种方法看起来不太好,而且我怀疑它是否有效。有没有更好的方法来实现这一点?
3条答案
按热度按时间xmq68pz91#
(np.select是向量化的if-elif-.. -else。)
得到
其中
dirs
是e4eetjau2#
您可以计算各行沿着的差异,然后检查一行中的所有差异是大于还是小于0:
whitzsjs3#
拟议代码:
结果: