[英]How to compare a value to the values of a column of a dataframe and find the potential rank?
我有一个四列的数据框 df ,如下所示:
timestamp values rank compare
t1 v1 1 c1
t1 v2 3 c1
t1 v3 2 c1
t2 v4 2 c2
t2 v5 3 c2
t2 v6 1 c2
t2 v7 4 c2
值 v 是在时间 t 的测量值。 这些值是排名的,最小值在排名 1 上,最大值在最大排名上。 此外,我对每个时间戳都有一个值 c。 现在我想添加一个额外的列并写出排名 c 如果它是其中的正常值。 所以结果可能是例如:
timestamp values rank compare rank_c
t1 v1 1 c1 2
t1 v2 3 c1 2
t1 v3 2 c1 2
t2 v4 2 c2 1
t2 v5 3 c2 1
t2 v6 1 c2 1
t2 v7 4 c2 1
到目前为止,我做了以下工作:
import pandas as pd
df_out = pd.DataFrame()
for ts in df['timestamp'].unique():
df_help = df.loc[df['timestamp'] == ts]
comp = df_help['compare'].iloc[0]
value_list = list(df_help['values'])
value_list.append(comp)
value_list.sort()
df_help['rank_c'] = value_list.index(comp) + 1
df_out = df_out.append(df_help, ignore_index = True)
它有效,但速度不是很快。 那么我怎样才能让它更快呢?
编辑添加具体示例:
给定数据帧 df:
timestamp values rank compare
12:00 0.23 1 0.42
12:00 0.45 3 0.42
12:00 0.37 2 0.42
14:00 0.33 2 0.22
14:00 0.54 3 0.22
14:00 0.17 1 0.22
14:00 0.76 4 0.22
考虑第一个时间戳 12:00:
timestamp values rank compare
12:00 0.23 1 0.42
12:00 0.45 3 0.42
12:00 0.37 2 0.42
现在我想找出如果比较中的值是值列中的条目(每个时间戳的每一行都相同),它会得到哪个排名。 在具体示例中,我们看到第一个时间戳的比较值将在第三个等级(而第二个时间戳的比较值将在第二个等级)。
所以预期的输出应该是:
timestamp values rank compare rank_c
12:00 0.23 1 0.42 3
12:00 0.45 3 0.42 3
12:00 0.37 2 0.42 3
14:00 0.33 2 0.22 2
14:00 0.54 3 0.22 2
14:00 0.17 1 0.22 2
14:00 0.76 4 0.22 2
我的解决方案如下:
def find_c(gb):
comp = gb['compare'].iloc[0]
value_list = gb['values'].tolist()
value_list.append(comp)
value_list.sort()
gb['rank_c'] = value_list.index(comp) + 1
return gb
df.groupby('timestamp').apply(find_c)
使用 pandas groupby.apply 而不是循环并将项目附加到新列表。 不确定它会批准多少,如果你可以测试它并向我展示结果,那就太棒了。
新版本:
@jezrael 的想法给了我一些启发。 我已经更新了函数,使用 np.where 查找并设置所有小于“比较”的“值”,然后找到结果的总数和加 1。
def find_c(gb):
gb['rank_c'] = np.where(gb['compare'] > gb['values'], 1, 0).sum()+1
return gb
df.groupby('timestamp').apply(find_c)
这种带np.where的方法好一点,比上面的方法节省5%的时间,更pythonic。
您可以使用GroupBy.transform
减去列并通过sum
计算低于0
的sum
的GroupBy.transform
:
df['compare'] = (df['values'].sub(df['compare']).le(0)
.groupby(df['timestamp'])
.transform('sum')
.add(1)
.astype(int))
print (df)
timestamp values rank compare
0 12:00 0.23 1 3
1 12:00 0.45 3 3
2 12:00 0.37 2 3
3 14:00 0.33 2 2
4 14:00 0.54 3 2
5 14:00 0.17 1 2
6 14:00 0.76 4 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.