Присвоить значение столбцу и сбросить после n-й строки

У меня есть фрейм данных pandas, который выглядит так...

индекс моя_колонка 0 1 2 3 4 5 6

Что мне нужно сделать, так это условно присвоить значения 'my_column' в зависимости от индекса. Первые три строки должны иметь значения «собака», «кошка», «птица». Затем в следующих трех рядах также должны быть слова «собака», «кошка», «птица». Этот шаблон должен применяться до конца набора данных.

индекс моя_колонка 0 собака 1 кот 2 птица 3 собака 4 кот 5 птица 6 собака

Я пробовал следующий код безрезультатно.

for index, row in df.iterrows():
    counter=3
    my_column='dog'
    if counter>3
    break
    else 
    counter+=1
    my_column='cat'
    counter+=1
    if counter>3
    break
    else 
    counter+=1
    my_column='bird'
    if counter>3
    break  

Как упоминалось в других ответах, ваш код содержит множество логических и синтаксических ошибок. Ключевое слово break используется для выхода из цикла. Вы никогда не сможете вернуться в цикл после выхода из него, поэтому, если вы хотите повторить элементы итерации, вам нужно оставаться в цикле, но найти способ сбросить свой счетчик. Этого проще всего добиться с помощью оператора по модулю: %. Это действительно изящный оператор с массой захватывающих математических свойств, известных под общим названием модульной арифметики.

ddejohn 23.11.2022 04:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
53
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Несколько проблем:

  1. Ваш синтаксис if неверен, вам не хватает двоеточий и правильного отступа
  2. Вы breakвыходите из своего цикла, прерывая его досрочно вместо использования структуры if, elif, else
  3. Вы пытаетесь обновить свой фрейм данных, перебирая его.

См. этот вопрос о том, почему вы не должны обновляться во время итерации.

Вместо этого вы могли бы сделать

values = ["dog", "cat", "bird"]

num_values = len(values)

for index in df.index():
    df.at[index, "my_column"] = values[index % num_values]
    

Я попробовал это решение, но получил следующую ошибку: объект «Int64Index» не может быть вызван. Я запускаю ваш код внутри функции.

ealfons1 23.11.2022 05:22

Расширенное индексирование

Одним из решений было бы превратить собаку-кошку-птицу в pd.Series и использовать расширенную индексацию:

dcb = pd.Series(["dog", "cat", "bird"])

df["my_column"] = dcb[df.index % len(dcb)].reset_index(drop=True)

Это работает, сначала создав массив индексов из df.index % len(dcb):

In [8]: df.index % len(dcb)
Out[8]: Int64Index([0, 1, 2, 0, 1, 2, 0], dtype='int64')

Затем, используя расширенную индексацию, вы можете выбрать элементы из dcb с помощью этого массива индексов:

In [9]: dcb[df.index % len(dcb)]
Out[9]:
0     dog
1     cat
2    bird
0     dog
1     cat
2    bird
0     dog
dtype: object

Наконец, обратите внимание, что индекс массива выше повторяется. Сбросьте его и удалите старый индекс с помощью .reset_index(drop=True) и, наконец, назначьте его вашему фрейму данных.

Использование генератора

Вот альтернативное решение, использующее бесконечный генератор собаки-кошки-птицы:

In [2]: df
Out[2]:
  my_column
0
1
2
3
4
5
6

In [3]: def dog_cat_bird():
   ...:     while True:
   ...:         yield from ("dog", "cat", "bird")
   ...:

In [4]: dcb = dog_cat_bird()

In [5]: df["my_column"].apply(lambda _: next(dcb))
Out[5]:
0     dog
1     cat
2    bird
3     dog
4     cat
5    bird
6     dog
Name: my_column, dtype: object

Я пробовал оба метода, но в результате присваивание новых значений по какой-то причине пропускало строку.

ealfons1 23.11.2022 05:23

Похоже, вы что-то неправильно скопировали. Без обид, но приведенный выше код является доказательством того, что решение делает именно то, о чем вы просили, а это означает, что в вашем конкретном фрейме данных есть что-то, что не соответствует вопросу. Не совсем понятно, что вы подразумеваете под "пропущенной строкой".

ddejohn 23.11.2022 05:27
Ответ принят как подходящий

Создайте словарь:

pet_dict = {0:'dog',
            1:'cat',
            2:'bird'}

Вы можете получить значение индекса, используя функцию .name и модуль (%) на 3, чтобы получить желаемый результат:

df.apply (lambda x: pet_dict[x.name%3],axis=1)
0     dog
1     cat
2    bird
3     dog
4     cat
5    bird
6     dog
7     cat
8    bird
9     dog

Спасибо. Я смог получить результат, который мне нужен с этим решением!

ealfons1 23.11.2022 05:18

Другие вопросы по теме