熊猫-查找列中最长的字符串值以及行ID

时间:2019-11-11 09:48:01

标签: python pandas

我正在尝试找到最长的字符串值连串以及它在哪里。 我的数据格式如下:

ID Datetime Name 
0  Date1,   Harald
1  Date2,   Harald
2  Date3,   Esther
3  Date4,   Steve
4  Date5,   Esther
5  Date6,   Esther
6  Date7,   Esther

预期输出将是此,按字符串值和日期或行号显示的最大条纹

Output = {
    Harald: 2, 0 or Date1
    Esther: 3, 4 or Date5
    Steve: 1, 3 or Date4
}

我最接近的解决方案是:

def getLongestStreak():
    s = df['Name']

    for index, (key, group) in enumerate(groupby(s.tolist())):
        grouplength = len(list(group))
        if key in longestStreakDict:
            if longestStreakDict[key][0] < grouplength:
                longestStreakDict[key] = grouplength, index
        else:
            longestStreakDict[key] = grouplength, index

不幸的是,此方法仅返回最长的条纹,其中包含在groupby迭代器中更改组的次数,它也使用itertools,并且对于大型数据集而言会很慢。

{'Harald': (2, 1), 'Esther': (3, 3), 'Steve': (1, 2)}

有人知道非迭代解决方案还返回正确的行索引吗?

1 个答案:

答案 0 :(得分:3)

我们可以使用Series.cumsum + Series.shift 根据连续的名称创建组(请参阅详细信息)。然后,您可以使用GroupBy.agg创建一个具有每个组大小的数据框。 ,每个组的第一个索引和日期时间值。 使用DataFrame.sort_values按大小对数据帧进行排序并删除重复项(可以使用DataFrame.drop_duplicates)删除具有相同名称和较小大小的组。 将列转换为str。 (如果您的实际数据不是str,则可能还需要转换Datetime)。然后,您可以使用Series.str.cat合并各列。最后,我们可以使用Series.to_dict + DataFrame.set_index来获得字典

groups=df['Name'].ne(df['Name'].shift()).cumsum()
df_agg= (   df.groupby(groups,sort=False).agg(Name=('Name','first'),
                                              Datemin=('Datetime','first'),
                                              length=('Name','size'),
                                              idxmin=('ID','idxmin'))
              .sort_values('length',ascending=False)
              .drop_duplicates('Name')
        )


df_agg['j1']=df_agg['length'].astype(str).str.cat(df_agg['idxmin'].astype(str),sep=',')
df_agg['j']=df_agg['j1'].str.cat(df_agg['Datemin'],sep=' or ')
print(df_agg)

        Name  length  idxmin Datemin   j1             j
Name                                                  
4     Esther       3       4   Date5  3,4  3,4 or Date5
1     Harald       2       0   Date1  2,0  2,0 or Date1
3      Steve       1       3   Date4  1,3  1,3 or Date4

my_dict=df_agg.set_index('Name')['j'].to_dict()
print(my_dict)

输出

{'Esther': '3,4 or Date5', 'Harald': '2,0 or Date1', 'Steve': '1,3 or Date4'}

详细信息:

print(groups)

0    1
1    1
2    2
3    3
4    4
5    4
6    4
Name: Name, dtype: int64