Передача значений из одного столбца в другой столбец в фрейме данных pandas на основе условий

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

У меня есть фрейм данных:

 df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
                   'B': [5, '-', '-', 8, 9],
                   'C': ['-', 'b', 'c', '-', 'e']})
  

Как я могу заменить значения, df['B'] используя соответствующие значения в df['C'] , если df['B']='-' и df['C']!= '-' .

Ожидаемый результат:

 ({'A': [0, 1, 2, 3, 4],
  'B': [5, 'b', 'c', 8, 9],
  'C': ['-', 'b', 'c', '-', 'e']})
  

Out

Я использовал:

 replace = (df['B'] == '-') amp; (df['C'] != '-')
df['B'][replace1] = df['C']
  

Есть ли лучший способ?

Ответ №1:

Попробуйте это :

 import numpy as np 
df['B']=np.where((df['B']=='-')amp;(df['C']!='-'),df['C'],df['B'])
  

Фрейм данных выглядит так :

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

Ответ №2:

Вы близки, используйте DataFrame.loc :

 replace = (df['B'] == '-') amp; (df['C'] != '-')
df.loc[replace, 'B'] = df['C']
print (df)
   A  B  C
0  0  5  -
1  1  b  b
2  2  c  c
3  3  8  -
4  4  9  e
  

Мне было любопытно, если np.where здесь быстрее, а при повторении выборки данных 100000 нет:

В реальных данных это должно быть разным, зависит от длины фрейма данных и количества совпадающих значений.

 df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
                   'B': [5, '-', '-', 8, 9],
                   'C': ['-', 'b', 'c', '-', 'e']})

#[500000 rows x 3 columns]
df = pd.concat([df] * 100000, ignore_index=True)

In [9]: %timeit df.loc[(df['B'] == '-') amp; (df['C'] != '-'), 'B'] = df['C']
60.7 ms ± 643 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [10]: %timeit df['B']=np.where((df['B']=='-')amp;(df['C']!='-'),df['C'],df['B'])
66 ms ± 324 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
  

Я думаю, что причина заключается np.where в обработке всех значений, loc только отфильтрованных значений. Также есть смешанные строки с числами.

Ответ №3:

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

 import pandas as pd
df = pd.DataFrame({'A': [0, 1, 2, 3, 4],
                   'B': [5, '-', '-', 8, 9],
                   'C': ['-', 'b', 'c', '-', 'e']})

for index, row in df.iterrows():
    if(row['B'] == '-' and row['C']!='-'):
       df.loc[index,'B'] = df.loc[index,'C']
  

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