Выполните итерацию по нескольким столбцам фрейма данных, которые содержат одну и ту же подстроку

#python #pandas

Вопрос:

Рассмотрим следующий фрейм данных:

Указатель фу Строка А бар Строка B
Первый 15 nan 0 3
Второй 0 2 25 nan

У меня есть следующая логика, которая позволяет мне перебирать один столбец фрейма данных, получать доступ к определенной ячейке и изменять ее значение. Если значение ячейки в столбце с именем String A НЕ NaN УКАЗАНО, то значение ячейки в столбце, которое предшествует ей, должно быть изменено на NaN

 for idx, val in enumerate(df['String A']):  if not math.isnan(val) :  df.iloc[: , df.columns.get_loc('String A')-1].iloc[idx] = np.nan  

Есть ли способ обобщить цикл, чтобы я мог выполнить итерацию по всем столбцам, содержащим подстроку String , таким образом, чтобы цикл применялся как к столбцам String A , так и String B (или к любому столбцу, содержащему эту подстроку).

Тогда таблица должна выглядеть следующим образом:

Указатель фу Строка А бар Строка B
Первый 15 nan nan 3
Второй nan 2 25 nan

Изменить: Добавлено больше деталей к вопросу

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

1. Итак , если «Строка A» отсутствует NaN , вы меняете значение из той же строки в «Col A»? Аналогично, «Строка B» изменила бы значение в «Col B»?

2. @не_спешал Точно. Если «Строка A» отсутствует NaN , я могу изменить значение столбца, который стоит перед этим столбцом, и так далее для каждого столбца с подстрокой «Строка».

3. На что вы меняете значение? Можете ли вы опубликовать реальный пример с фиктивными значениями вместо «строка»»строка»? А также ваши ожидаемые результаты?

4. @not_speshal Хорошо, я отредактирую вопрос сейчас

Ответ №1:

Попробуй:

 for idx in [i for i, c in enumerate(df.columns) if c.startswith("String")]:  df.iloc[:, idx-1] = df.iloc[:, idx-1].where(df.iloc[:,idx].isnull())  gt;gt;gt; df  foo String A bar String B Index  First 15.0 NaN NaN 3.0 Second NaN 2.0 25.0 NaN  

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

1. Извините, что не сделал таблицу достаточно сложной. Я не знал этого имени Col A и Col B не имел к нему отношения. Имена этих столбцов могут быть любыми строками (например, lt;foogt;, lt;foogt;lt;bargt;), поэтому lt;bargt; lstrip не будет работать

2. Вот почему я специально спросил, изменяет ли строка A значение A, а Строка B значение B. На что вы ответили утвердительно.

3. Вы никогда не спрашивали меня, были ли это настоящие названия столбцов. Но шаблон для String A все еще сохраняется. Col A или Col B , однако, это может быть любая случайная строка

4. @DanG — Я указал, что «Строка B» изменит значение в «Col B» . В любом случае отредактируйте ответ.

5. Спасибо! Это решает мою проблему

Ответ №2:

Чтобы сохранить использование вашего исходного цикла for, вы можете сделать следующее:

 for idx, val in enumerate(df):   if 'String' in val:   print(val)