首页 > 解决方案 > 检查 pandas 列的连续行值

问题描述

我有:

    hi     

0    1      
1    2      
2    4      
3    8    
4    3     
5    3    
6    2   
7    8    
8    3   
9    5     
10    4  

我有一个列表和单个整数的列表,如下所示:

[[2,8,3], 2, [2,8]]

对于主列表中的每个项目,我想找出它第一次出现在列中的索引。

因此,对于单个整数(即 2),我想知道它第一次出现在 hi 列中的时间(索引 1,但当它再次出现时我不感兴趣,即索引 6)

对于列表中的列表,我想知道列表在该列中按顺序出现的最后一个索引。

因此,对于在索引 6、7 和 8 处按顺序出现的 [2,8,3],我希望返回 8。请注意,它也出现在此之前,但被 4 插入,所以我对此不感兴趣。

到目前为止,我使用过:

for c in chunks:

        # different method if single note chunk vs. multi

        if type(c) is int:
           # give first occurence of correct single notes
           single_notes = df1[df1['user_entry_note'] == c]
           single_notes_list.append(single_notes)

        # for multi chunks
        else:
            multi_chunk = df1['user_entry_note'].isin(c)
            multi_chunk_list.append(multi_chunk)

标签: pythonpandasdataframe

解决方案


你可以用np.logical_and.reduce+来做shift。但是有很多边缘情况需要处理:

import numpy as np

def find_idx(seq, df, col):
    if type(seq) != list:     # if not list
        s = df[col].eq(seq)
        if s.sum() >= 1:      # if something matched
            idx = s.idxmax().item()
        else:
            idx = np.NaN
    elif seq:                 # if a list that isn't empty
        seq = seq[::-1]       # to get last index
        m = np.logical_and.reduce([df[col].shift(i).eq(seq[i]) for i in range(len(seq))])
        s = df.loc[m]
        if not s.empty:       # if something matched
            idx = s.index[0]
        else:
            idx = np.NaN
    else:                     # empty list
        idx = np.NaN
    return idx

l = [[2,8,3], 2, [2,8]]
[find_idx(seq, df, col='hi') for seq in l]
#[8, 1, 7]

l = [[2,8,3], 2, [2,8], [], ['foo'], 'foo', [1,2,4,8,3,3]]
[find_idx(seq, df, col='hi') for seq in l]
#[8, 1, 7, nan, nan, nan, 5]

推荐阅读