Добавить индекс к дублирующимся элементам в серии Pandas

#python #pandas #duplicates #series

#python #pandas #дубликаты #Серии

Вопрос:

Я написал следующую функцию для добавления индексов к дубликатам в серии:

( ["foo", "foo", "foo", "bar", "bar"] становится ["foo 1", "foo 2", "foo 3", "bar 1", "bar 2"] )

 def indexer(series):
  all_labels = []
  for title in set(series): 
    label = []
    i = 0
    while i < len(series): 
      if title == series.iloc[i]:
        label.append(title)
      i  = 1
    all_labels.append(label)
  final = []
  for item in all_labels:
    if len(item) > 1:
      for i, label in enumerate(item):
        final.append(label   " "   str(i 1))
    else:
      final.append(item[0])
  return final
  

Очевидно, что есть лучший и более чистый способ сделать это, вероятно, используя Pandas groupby и agg (хотя я не уверен, как они ведут себя с одной серией вместо df). Не мог бы кто-нибудь, пожалуйста, пролить свет на то, как это сделать? Спасибо

Ответ №1:

Если это фрейм данных, который вы можете использовать groupby для поиска совокупного количества, которое является меткой, которую вы хотите объединить со всеми вашими строками, и обратите внимание, что группы не обязательно должны быть в порядке:

 df = pd.DataFrame(["foo", "foo", "bar", "bar", "foo"], columns=["baz"])
labels = df.groupby("baz").cumcount()   1
df["baz"]   " "   labels.astype(str)
  

что приводит к

 0    foo 1
1    foo 2
2    bar 1
3    bar 2
4    foo 3
dtype: object
  

Однако это также добавит 1 метку к любым уникальным значениям. Вы хотели, чтобы они оставались неизменными? Я предположил, что нет, поскольку вы запускаете другие в 1 вместо того, чтобы оставлять первое в каждой группе неизменным.

Комментарии:

1. Я действительно хотел, чтобы уникальные значения оставались неизменными, но с вашим результатом я могу просто удалить «1» из значений, которых нет в df [df.duplicated()], верно?

Ответ №2:

Если необходимо оставить один внешний вид в покое.

[‘foo’, ‘foo’, ‘foo’, ‘bar’, ‘bar’, ‘John’]

 mylist = list(df)
m = map(lambda x: x[1]  " "   str(mylist[:x[0]].count(x[1])   1) if mylist.count(x[1]) > 1 else x[1], enumerate(mylist))
m = list(m)
df = pd.Series(m)
df
  

Вывод:

 0    foo 1
1    foo 2
2    foo 3
3    bar 1
4    bar 2
5    John
dtype: object
  

Джон не получил от него никакого номера. Ура!

Комментарии:

1. также отличный ответ, не был выбран как правильный, потому что другой более «пандонический». Однако это дает результаты, которые мне были нужны

2. прекрасно ….! <3