Изменение и замена значений в строке и столбце по условиям

#python #pandas #dataframe #conditional-statements

#python #pandas #фрейм данных #условные операторы

Вопрос:

У меня есть следующий фрейм данных pandas:

введите описание изображения здесь

и я хочу проверить, является ли значение в столбце 'A start' отрицательным. Если это так, то поменяйте местами значения в столбце 'start' и 'end' и в столбцах 'A start' и 'A end' в строке, где значение 'A start' имеет отрицательное значение. Таким образом, результат должен быть:

введите описание изображения здесь

Я пытался решить это с where помощью, но это не работает.

 df[['A start','A end']] = df[['A end','A start']].where(df['A start'] < 0 , df[['A start','A end']].values)
 

Я использую Python 3.8.

Большое вам спасибо за вашу помощь.

PS: существующий вопрос здесь, на форуме:

 What is correct syntax to swap column values for selected rows in a pandas data frame using just one line?
 

к сожалению, не помогает.

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

1. Не могли бы вы, пожалуйста, не публиковать скриншоты? Опубликуйте данные и то, что вы сделали до сих пор, чтобы решить проблему. Спасибо!

2. Я добавил код, который использовал. Спасибо за ваш комментарий.

Ответ №1:

Этот код переставляет значения между начальным и конечным столбцами, если начальное значение меньше нуля:

 for i, row in df.iterrows():
    if row['A start'] < 0:
        start_value = row['start']
        end_value = row['end']
        df.iloc[i, df.columns.get_loc('start')] = end_value
        df.iloc[i, df.columns.get_loc('end')] = start_value
 

i это индекс и row словарь со значениями столбцов.

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

1. Спасибо за ответ, к сожалению, не работает.

2. Не могли бы вы предоставить мне выходные данные при использовании этого кода? Кроме того, не могли бы вы предоставить мне фрейм данных, который используется для его тестирования?

Ответ №2:

Хотя цикл не очень эффективен в фреймах данных, я думаю, вы могли бы сделать следующее: сохраните исходные значения в переменные и обновите значения с помощью «df.at »

 for index, row in df.iterrows():
if row['A start'] < 0:
    orig_start = row['start']
    orig_end = row['end']

    orig_A_start = row['A start']
    orig_A_end = row['A end']

    df.at[index, 'start'] = orig_end
    df.at[index, 'end'] = orig_start

    df.at[index, 'A start'] = orig_A_end
    df.at[index, 'A end'] = orig_A_start
 

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

1. Спасибо за ответ, к сожалению, не работает.

2. Можете ли вы сказать, в чем проблема? не происходит замена значений или выдача ошибки?

3. df[[‘start’,’end’]] = df[[‘end’,’start’]].где(df[‘A start’] < 0 , df[[‘start’,’end’]].значения) df[[‘A start’,’A end’]] = df[[‘A end’,’A start’]].где(df[‘A start’] < 0 , df[[‘A start’,’A end’]].значения) С этим кодом это сработало. Цикл For слишком сложно импортировать в мой код.

4. Всегда есть больше решений одной и той же проблемы — цикл for входит в стандартную библиотеку python и является частью любого объектно-ориентированного языка, который вы изучаете. Существует большая разница между — что-то не работает или имеет более элегантный способ ее решения. Я рад, что вы нашли решение.

Ответ №3:

Предполагая, что одно из двух всегда будет отрицательным, это так же просто, как упорядочение по max / min

 df[['A start','A end']] = df[['A start','A end']].agg([max,min],axis=1)
 

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

1. Спасибо, это единственный подход, который работает. Но как поменять местами значения в начальных и конечных столбцах?

Ответ №4:

Сделайте это:

 import numpy as np
df3 = pd.read_csv(r"c:/users/k_sego/perce.csv",sep=";")
 

что дает

   Start   end   A Start   A end
0      1     4       234    -654
1      5     6      -475     312
2      7     8      -765     987
3      2     9       113    -553
 

и для реорганизации

 df3['A Start'],df3['A end']=np.where(df3['A Start']< 0,(df3['A end'],df3['A Start']),(df3['A Start'],df3['A end']))
 

который возвращает

   Start   end   A Start   A end
0      1     4       234    -654
1      5     6       312    -475
2      7     8       987    -765
3      2     9       113    -553
 

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

1. Это именно тот подход, который я тестировал ранее, но он не работает. Значения в столбцах start и end также должны меняться местами, когда Start является отрицательным.

2. Это работает для меня, как вы можете видеть из вывода, который я опубликовал. Вы проверили dtype в своих фреймах данных?

3. Я делаю то же самое (чтение csv). Может ли это быть проблемой, потому что здесь используется np, и я работаю с фреймами данных pandas?

Ответ №5:

 df[['start','end']] = df[['end','start']].where(df['A start'] < 0 , df[['start','end']].values) 

df[['A start','A end']] = df[['A end','A start']].where(df['A start'] < 0 , df[['A start','A end']].values)