尝试获取 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