【问题标题】:Updating a DataFrame column using logical comparison使用逻辑比较更新 DataFrame 列
【发布时间】:2022-01-21 02:29:37
【问题描述】:

根据以下建议,我已将数据框合并到一个 DF 中。因此也更改了标题。以下是我合并的数据框的屏幕截图:

我现在需要将 Adj Close 与其余列进行比较,以准确了解它的位置 - 例如是在 PP 和 R1、R1 和 R2、R2 和 R3 等之间吗?基于此,我需要创建一个新的 Status 列,该列将具有相关的状态。我写的函数如下

def check_status(merged):
if merged['Adj Close'] < merged['R3']:
    merged['Status'] = 'Breached R3'
elif merged['R3'] < merged['Adj Close'] < merged['R2']:
    merged['Status'] = 'Breached R2'
elif merged['R2'] < merged['Adj Close'] < merged['R1']:
    merged['Status'] = 'Breached R1'
elif merged['R1'] < merged['Adj Close'] < merged['PP']:
    merged['Status'] = 'Breached PP on lower side'
elif merged['PP'] < merged['Adj Close'] < merged['S1']:
    merged['Status'] = 'Breached PP on higher side'
elif merged['S1'] < merged['Adj Close'] < merged['S2']:
    merged['Status'] = 'Breached S1'
elif merged['S2'] < merged['Adj Close'] < merged['S3']:
    merged['Status'] = 'Breached S2'
else:
    merged['Status'] = 'Breached S3'
return merged

这会产生如下错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

接下来我尝试使用 np.where()。代码 sn-p 如下:

merged['Status'] = np.where(merged['Adj Close'] < merged['R3'], 'Breached R3', merged['Adj Close'])
merged['Status'] = np.where(merged['R2'] < merged['Adj Close'] < merged['R1'], 'Breached R1', merged['Adj Close'])
merged['Status'] = np.where(merged['R1'] < merged['Adj Close'] < merged['PP'], 'Breached PP on lower side', merged['Adj Close'])
merged['Status'] = np.where(merged['PP'] < merged['Adj Close'] < merged['S1'], 'Breached PP on higher side', merged['Adj Close'])
merged['Status'] = np.where(merged['S1'] < merged['Adj Close'] < merged['S2'], 'Breached S1', merged['Adj Close'])
merged['Status'] = np.where(merged['S2'] < merged['Adj Close'] < merged['S3'], 'Breached S2', merged['Adj Close'])
merged['Status'] = np.where(merged['S3'] < merged['Adj Close'], 'Breached S3', merged['Adj Close'])

但是,我得到了同样的错误。

如上更新状态栏需要哪些选项?

我有一个很大的 DF,所以性能可能是一个考虑因素。

【问题讨论】:

  • 请您提供数据框的样本吗?
  • 使用函数join在索引上合并dfs,或merge在列上合并它们。
  • 我回滚了你最近的编辑;非常欢迎您将您的解决方案作为答案发布(并在可能的情况下接受它,以实际上将其标记为已解决),但您的问题应该严格保持为一个问题。

标签: python pandas dataframe


【解决方案1】:

np.select 与整个数据框一起使用。

conditions = [
    df['Adj Close'] < df['R3'],
    (df['R2'] < df['Adj Close']) & (df['Adj Close'] < df['R1']),
    (df['R1'] < df['Adj Close']) & (df['Adj Close'] < df['PP']),
    (df['PP'] < df['Adj Close']) & (df['Adj Close'] < df['S1']),
    (df['S1'] < df['Adj Close']) & (df['Adj Close'] < df['S2']),
    (df['S2'] < df['Adj Close']) & (df['Adj Close'] < df['S3']),
    df['S3'] < df['Adj Close']
]

values = [
    'Breached R3',
    'Breached R1',
    'Breached PP on lower side',
    'Breached PP on higher side',
    'Breached S1',
    'Breached S2',
    'Breached S3'
]

df['Status'] = np.select(conditions, values, df['Adj Close'])

这将显着加快您的程序@Sachin

【讨论】:

  • @Sachin 检查这个答案。它将有助于实现矢量化并显着加快代码速度。
  • 优秀!!!这正是我想要的!!!
【解决方案2】:

我在for 循环中使用np.where() 解决了这个问题:

for i in merged:
    merged['Status'] = np.where(merged['Adj Close'] > merged['R3'], 'Breached R3', merged['Status'])
    merged['Status'] = np.where(np.logical_and(merged['R3'] > merged['Adj Close'], merged['Adj Close'] > merged['R2']), 'Breached R2', merged['Status'])
    merged['Status'] = np.where(np.logical_and(merged['R2'] > merged['Adj Close'], merged['Adj Close'] > merged['R1']), 'Breached R1', merged['Status'])
    merged['Status'] = np.where(np.logical_and(merged['R1'] > merged['Adj Close'], merged['Adj Close'] > merged['PP']), 'Breached PP on higher side', merged['Status'])
    merged['Status'] = np.where(np.logical_and(merged['PP'] > merged['Adj Close'], merged['Adj Close'] > merged['S1']), 'Breached PP onn lower side', merged['Status'])
    merged['Status'] = np.where(np.logical_and(merged['S1'] > merged['Adj Close'], merged['Adj Close'] > merged['S2']), 'Breached S1', merged['Status'])
    merged['Status'] = np.where(np.logical_and(merged['S2'] > merged['Adj Close'], merged['Adj Close'] > merged['S3']), 'Breached S2', merged['Status'])
    merged['Status'] = np.where(merged['S3'] > merged['Adj Close'] , 'Breached S3', merged['Status'])

非常感谢所有建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2010-12-24
    相关资源
    最近更新 更多