#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']})
Я использовал:
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']