Python 如何将一个值与数据帧列的值进行比较,并找到潜在的秩?
我有一个dataframe df,有四列,如下所示:Python 如何将一个值与数据帧列的值进行比较,并找到潜在的秩?,python,python-3.x,pandas,sorting,Python,Python 3.x,Pandas,Sorting,我有一个dataframe 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是
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时刻的测量值。该值按s.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
现在我想知道,如果比较中的值是values列中的一个条目,那么比较中的值将得到哪个等级(每个时间戳的每一行都是相同的)。在具体的示例中,我们看到第一个时间戳的比较值将位于第三级(第二个时间戳的比较值将位于第二级)
因此,预期产出应为:
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,而不是循环并将项目附加到新列表中。不知道它会被批准多少,如果你能测试它并给我看结果,那就太棒了
新版:
@耶斯雷尔的想法给了我一些启示。我已经更新了函数,使用np.where查找并设置了所有小于“compare”的“value”,然后找到结果的总和加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%的时间,并且更具python性。我的解决方案如下:
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,而不是循环并将项目附加到新列表中。不知道它会被批准多少,如果你能测试它并给我看结果,那就太棒了
新版:
@耶斯雷尔的想法给了我一些启示。我已经更新了函数,使用np.where查找并设置了所有小于“compare”的“value”,然后找到结果的总和加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%的时间,并且更具python风格。您可以使用以下方法减去列并计算低于
0
的值的数量:
您可以减去列,并通过
sum
计算0
以下的值的数量,方法是:
rank
中的值基于时间戳内的排名,对吗?rank\u c
中的值如何?它们是否也应该基于时间戳组?因为对于每个时间戳组,rank\u c
中的值似乎是恒定的。您可以创建吗?因为现在所有数据在新列的示例数据框中都是1,rank
中的值基于时间戳内的秩,对吗?rank\u c
中的值如何?它们是否也应该基于时间戳组?因为对于每个时间戳组,rank\u c
中的值似乎是恒定的。您可以创建吗?因为现在新列中的示例数据框中的所有数据都是1谢谢,您的解决方案要快得多。我的尝试:232ms±21.5ms/循环(平均值±标准偏差3次,每个循环1次)你的:33.9ms±6.06ms/循环(平均值±标准偏差3次,每个循环10次)用于100行的数据帧这很好。非常感谢,您的解决方案要快得多。我的尝试:232ms±21.5ms/循环(平均值±标准偏差3次,每个循环1次)你的:33.9ms±6.06ms/循环(平均值±标准偏差3次,每个循环10次)用于100行的数据帧这很好。AwesomeI喜欢这个想法(并尝试了类似的方法),但它比@Shengs方法慢一点。每个循环38.3 ms±5.2 ms(平均±标准偏差100次,每个循环10次),相比之下,每个循环33.9 ms±6.06 ms(平均±标准偏差3次,每个循环10次),您是对的,但我使用的数据帧比测试df大得多timing@Philipp-好的,没问题;)我喜欢这个想法(并尝试了类似的方法),但它比@Shengs方法慢一点。每个循环38.3 ms±5.2 ms(平均±标准偏差100次,每个循环10次),相比之下,每个循环33.9 ms±6.06 ms(平均±标准偏差3次,每个循环10次),您是对的,但我使用的数据帧比测试df大得多timing@Philipp-好的,没问题;)