繁体   English   中英

如何将值与数据框列的值进行比较并找到潜在排名?

[英]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计算低于0sumGroupBy.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM