You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于另一DataFrame单元格值赋值Python DataFrame单元格的问题

问题:基于DataFrame单元格值的状态切换赋值

我需要根据DataFrame(df1)的单元格值,给同尺寸(索引与列一致)的DataFrame(df2)赋值,规则如下:

  • df2所有单元格默认值为0
  • 若df1某列出现连续两个1,则将df2对应列的第二个位置设为1,后续该列单元格保持1,直到df1该列出现连续两个-1
  • 当df1某列出现连续两个-1时,将df2对应列的第二个位置设为0,后续保持0,直到df1该列再次出现连续两个1,重复上述逻辑

编写的代码触发错误:

ValueError: Location based indexing can only have [integer, integer slice (START point is INCLUDED, END point is EXCLUDED), listlike of integers, boolean array] types

示例数据与代码

输入数据与初始代码

import pandas as pd

dic_in = {'A':[0, 1, 1, 0, -1, -1, 0],
         'B':[-1, 0, 0, 1, 1, -1, -1]}
index = pd.date_range('1/2/1998', '1/8/1998', freq='D')
df1 = pd.DataFrame(dic_in, index=index)
df1_prev = df1.shift(1)

df2 = df1.copy()*0

for j in df1.columns:
    for idx in df1.index:
        if(df1.iloc[idx,j]==1) & (df1_prev.iloc[idx,j]==1):
            df2.iloc[idx,j] = 1
        elif(df1.iloc[idx,j]!=-1) & (df1_prev.iloc[idx,j]==1):
            df2.iloc[idx,j] = 1
        else:
            df2.iloc[idx,j] = 0

df1实际数据

A  B
1998-01-02  0 -1
1998-01-03  1  0
1998-01-04  1  0
1998-01-05  0  1
1998-01-06 -1  1
1998-01-07 -1 -1
1998-01-08  0 -1

期望的df2输出

A  B
1998-01-02  0  0
1998-01-03  0  0
1998-01-04  1  0
1998-01-05  1  0
1998-01-06  0  1
1998-01-07  0  1
1998-01-08  0  0

问题分析与修复

错误原因

代码中使用iloc[idx,j]时,idx是日期类型的索引,而iloc仅支持整数、整数切片、整数列表或布尔数组类型的索引,这直接触发了类型错误。

修复后的代码

通过逐列跟踪状态的方式实现需求,既避开索引错误,又准确实现状态切换逻辑:

import pandas as pd

dic_in = {'A':[0, 1, 1, 0, -1, -1, 0],
         'B':[-1, 0, 0, 1, 1, -1, -1]}
index = pd.date_range('1/2/1998', '1/8/1998', freq='D')
df1 = pd.DataFrame(dic_in, index=index)

# 初始化df2为全0
df2 = pd.DataFrame(0, index=df1.index, columns=df1.columns)

for col in df1.columns:
    # 预先标记触发状态切换的位置
    # 连续两个1的第二个位置
    trigger_up = (df1[col] == 1) & (df1[col].shift(1) == 1)
    # 连续两个-1的第二个位置
    trigger_down = (df1[col] == -1) & (df1[col].shift(1) == -1)
    
    current_state = 0  # 初始状态为0
    for i in range(len(df1)):
        # 检查当前位置是否触发状态切换
        if trigger_up.iloc[i]:
            current_state = 1
        elif trigger_down.iloc[i]:
            current_state = 0
        # 第一个位置永远是0,从第二个位置开始赋值当前状态
        if i > 0:
            df2.iloc[i, df2.columns.get_loc(col)] = current_state

print(df2)

验证结果

运行代码后输出与期望完全一致,同时解决了索引错误的问题。

逻辑说明

  1. 用trigger_up和trigger_down预先标记每列中触发状态切换的位置,逻辑更清晰
  2. 逐列维护current_state变量,跟踪当前应该输出的0/1状态
  3. 使用整数索引访问iloc,避免日期索引的类型错误
  4. 第一个位置保持默认0,因为没有前一个值可以构成连续的1或-1

内容的提问来源于stack exchange,提问作者VChopra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:17:47