基于另一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)
验证结果
运行代码后输出与期望完全一致,同时解决了索引错误的问题。
逻辑说明
- 用
trigger_up和trigger_down预先标记每列中触发状态切换的位置,逻辑更清晰 - 逐列维护
current_state变量,跟踪当前应该输出的0/1状态 - 使用整数索引访问
iloc,避免日期索引的类型错误 - 第一个位置保持默认0,因为没有前一个值可以构成连续的1或-1
内容的提问来源于stack exchange,提问作者VChopra
相关产品推荐
相关产品推荐

