尝试获取 pandas 数据帧上的 i+1 索引失败
Trying to get the i+1 index on pandas dataframe failling
我正在尝试循环遍历数据帧以便比较 i 和 i+1 索引,如下所示:
d = {'col1': [1, 2,0,55,12,1, 3,1,56,13], 'col2': [3,4,44,34,46,2,3,43,35,47], 'col3': ['A','A','A','B','B','A','B','B','B','B'] }
df = pd.DataFrame(data=d)
df
for index, row in df.iterrows():
if df.at[index,"col3"] != df.at[index+1,"col3"]:
print('True')
else:
print("false")
我收到这个错误:
false
false
True
false
True
True
false
false
false
KeyError Traceback (most recent
call last)
in ()
3
4 for index, row in df.iterrows():
----> 5 if df.at[index,"col3"] != df.at[index+1,"col3"]:
6 print('True')
7 else:
in getitem(self, key)
2140
2141 key = self._convert_key(key)
-> 2142 return self.obj._get_value(*key, takeable=self._takeable)
2143
2144 def setitem(self, key, value):
2538 try:
-> 2539 return engine.get_value(series._values, index)
2540 except (TypeError, ValueError):
2541
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item()
KeyError: 10
你的代码总是在最后一行失败,因为你试图获取最后一行。
一般来说,当使用两个不同大小的列表进行这种迭代时,zip
函数是最好的解决方案:
for this_row, next_row in zip(df["col3"], df["col3"][1:]):
if this_row != next_row:
print('True')
else:
print("false")
请注意,即使您的数据框只有一个元素,此代码也不会抛出异常。
如果更喜欢使用索引进行迭代,另一种选择是:
for this_index, next_index in zip(df.index, df.index[1:]):
if df.at[this_index,"col3"] != df.at[next_index,"col3"]:
print('True')
else:
print("false")
下面是我将如何做。它可能不是最佳解决方案,但它应该可以帮助您解决问题。
关于pandas抛出异常的原因,请看下面的注释。
我把它作为一个函数的原因是你可以在以后为不同的数据帧/任务重用相同的函数。
此外,我个人的习惯是在迭代dataframe时,不需要value,我会避免使用iter_row方法(这种方法在处理大数据时可能计算量大。但它是仅基于我的个人经验)。
我很乐意看到其他人提供的其他绝妙解决方案!
def identify_same_or_not(data=None,col_index=None):
### 1: holder is the final result from comparation
holder = []
### 2: Since we are only interested in row index, iter_row might not needed
# Since we trying to compare x with x + 1, we need set the index loop as range(len(length_of_data) - 1)
# otherwise, in the final iteration (based on the example you provided), pd will try to compare row 9 with row 10,
# However, Row 10 does not exist in df; therefore, pd will throw exception
for row_index in range(len(df)-1):
# Same logic as you provided
if data.iloc[row_index,col_index] != df.iloc[row_index + 1,col_index]:
holder.append(True)
else:
holder.append(False)
return holder
我正在尝试循环遍历数据帧以便比较 i 和 i+1 索引,如下所示:
d = {'col1': [1, 2,0,55,12,1, 3,1,56,13], 'col2': [3,4,44,34,46,2,3,43,35,47], 'col3': ['A','A','A','B','B','A','B','B','B','B'] }
df = pd.DataFrame(data=d)
df
for index, row in df.iterrows():
if df.at[index,"col3"] != df.at[index+1,"col3"]:
print('True')
else:
print("false")
我收到这个错误:
false
false
True
false
True
True
false
false
false
KeyError Traceback (most recent call last) in () 3 4 for index, row in df.iterrows(): ----> 5 if df.at[index,"col3"] != df.at[index+1,"col3"]: 6 print('True') 7 else:
in getitem(self, key) 2140 2141 key = self._convert_key(key) -> 2142 return self.obj._get_value(*key, takeable=self._takeable) 2143 2144 def setitem(self, key, value):
2538 try: -> 2539 return engine.get_value(series._values, index) 2540 except (TypeError, ValueError): 2541 pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value() pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value() pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item() KeyError: 10
你的代码总是在最后一行失败,因为你试图获取最后一行。
一般来说,当使用两个不同大小的列表进行这种迭代时,zip
函数是最好的解决方案:
for this_row, next_row in zip(df["col3"], df["col3"][1:]):
if this_row != next_row:
print('True')
else:
print("false")
请注意,即使您的数据框只有一个元素,此代码也不会抛出异常。
如果更喜欢使用索引进行迭代,另一种选择是:
for this_index, next_index in zip(df.index, df.index[1:]):
if df.at[this_index,"col3"] != df.at[next_index,"col3"]:
print('True')
else:
print("false")
下面是我将如何做。它可能不是最佳解决方案,但它应该可以帮助您解决问题。
关于pandas抛出异常的原因,请看下面的注释。
我把它作为一个函数的原因是你可以在以后为不同的数据帧/任务重用相同的函数。
此外,我个人的习惯是在迭代dataframe时,不需要value,我会避免使用iter_row方法(这种方法在处理大数据时可能计算量大。但它是仅基于我的个人经验)。
我很乐意看到其他人提供的其他绝妙解决方案!
def identify_same_or_not(data=None,col_index=None):
### 1: holder is the final result from comparation
holder = []
### 2: Since we are only interested in row index, iter_row might not needed
# Since we trying to compare x with x + 1, we need set the index loop as range(len(length_of_data) - 1)
# otherwise, in the final iteration (based on the example you provided), pd will try to compare row 9 with row 10,
# However, Row 10 does not exist in df; therefore, pd will throw exception
for row_index in range(len(df)-1):
# Same logic as you provided
if data.iloc[row_index,col_index] != df.iloc[row_index + 1,col_index]:
holder.append(True)
else:
holder.append(False)
return holder