2024-04-25 01:54:10 发布
网友
我有一个场景,在这个场景中,我的pandas数据帧有一个存储为字符串的条件,我需要执行该条件并将结果存储为不同的列。下面的例子将帮助您更好地理解
现有数据帧:
ID Val Cond 1 5 >10 1 15 >10
预期数据帧:
ID Val Cond Result 1 5 >10 False 1 15 >10 True
如您所见,我需要连接Val和Cond,并在行级别执行eval
您也可以这样做:
df["Result"] = [eval(x + y) for x, y in zip(df["Val"].astype(str), df["Cond"]]
通过连接字符串df[“Val”]和df[“Cond”],然后对其应用eval,生成“Result”列
如果您的条件是由基本操作(<;、<;=、=、!=、>;、>;=)形成的,那么我们可以使用getattr更有效地实现这一点。我们使用.str.extract来解析条件,并将比较和值分开。使用我们的字典,我们将比较映射到系列属性,然后我们可以在一个简单的groupby中分别调用每个唯一的比较
getattr
.str.extract
import pandas as pd print(df) ID Val Cond 0 1 5 >10 1 1 15 >10 2 1 20 ==20 3 1 25 <=25 4 1 26 <=25 # All operations we might have. d = {'>': 'gt', '<': 'lt', '>=': 'ge', '<=': 'le', '==': 'eq', '!=': 'ne'} # Create a DataFrame with the LHS value, comparator, RHS value tmp = pd.concat([df['Val'], df['Cond'].str.extract('(.*?)(\d+)').rename(columns={0: 'cond', 1: 'comp'})], axis=1) tmp[['Val', 'comp']] = tmp[['Val', 'comp']].apply(pd.to_numeric) # Val cond comp #0 5 > 10 #1 15 > 10 #2 20 == 20 #3 25 <= 25 #4 26 <= 25 #5 10 != 10 # Aligns on row Index df['Result'] = pd.concat([getattr(gp['Val'], d[idx])(gp['comp']) for idx, gp in tmp.groupby('cond')]) # ID Val Cond Result #0 1 5 >10 False #1 1 15 >10 True #2 1 20 ==20 True #3 1 25 <=25 True #4 1 26 <=25 False #5 1 10 !=10 False
简单但低效且危险的方法是在每一行上eval,创建一个条件字符串eval是危险的,因为它可以计算任何代码,所以只有在您真正信任并了解数据的情况下才使用
eval
df['Result'] = df.apply(lambda x: eval(str(x.Val) + x.Cond), axis=1) # ID Val Cond Result #0 1 5 >10 False #1 1 15 >10 True #2 1 20 ==20 True #3 1 25 <=25 True #4 1 26 <=25 False #5 1 10 !=10 False
您也可以这样做:
通过连接字符串df[“Val”]和df[“Cond”],然后对其应用eval,生成“Result”列
如果您的条件是由基本操作(<;、<;=、=、!=、>;、>;=)形成的,那么我们可以使用
getattr
更有效地实现这一点。我们使用.str.extract
来解析条件,并将比较和值分开。使用我们的字典,我们将比较映射到系列属性,然后我们可以在一个简单的groupby中分别调用每个唯一的比较简单但低效且危险的方法是在每一行上
eval
,创建一个条件字符串eval
是危险的,因为它可以计算任何代码,所以只有在您真正信任并了解数据的情况下才使用相关问题 更多 >
编程相关推荐