#python #pandas #performance #dataframe #filter
#python #pandas #Производительность #фрейм данных #Фильтр
Вопрос:
на данный момент я работаю над проектом и столкнулся с некоторой проблемой эффективности. В какой-то момент у меня огромный фрейм данных, и мне нужно удалить строки. Мой фрейм данных содержит два столбца, где значение равно либо ‘0’, ‘1’, либо другому np.nan.
Мне нужно удалить все строки, где первый столбец равен «0», а другой — «1» или наоборот. Я хочу сохранить все остальные комбинации.
Я написал функцию, которая выполняет эту работу, но она крайне неэффективна и занимает много времени. Вот пример ввода, моей функции и ожидаемого результата.
data = {'val': ['a', 'b', 'c'],
'compare1': ['0', '0', '1'],
'compare2': ['0', None, '0']
}
df = pd.DataFrame (data)
df
> val compare1 compare2
> 0 a 0 0
> 1 b 0 None
> 2 c 1 0
моя функция:
def filter_df(df, colname1, colname2):
for index, row in df.iterrows():
if (row[colname1] == "0") and (row[colname2] == "1"):
df.drop(index, inplace=True)
if (row[colname1] == "1") and (row[colname2] == "0"):
df.drop(index, inplace=True)
return df
результат, который я хочу иметь и получать с помощью fkt:
df_new = filter_df(df,'compare1', 'compare2')
df_new
> val compare1 compare2
> 0 a 0 0
> 1 b 0 None
Если у вас есть идея сделать его более эффективным, пожалуйста, дайте мне знать :-). Я очень рад любой помощи.
Лучший P
Ответ №1:
вы можете использовать такие условия:
mask1 = ~((df['compare1'] == "0") amp; (df['compare2'] == "1"))
mask2 = ~((df['compare1'] == "1") amp; (df['compare2'] == "0"))
df = df[mask1 amp; mask2 ]
если производительность по-прежнему неэффективна для вас, я бы посоветовал вам перейти на numpy для повышения производительности…
Ответ №2:
Вы можете преобразовать фрейм данных в числовые типы :
df = df.transform(pd.to_numeric, errors="ignore")
df
val compare1 compare2
0 a 0 0.0
1 b 0 NaN
2 c 1 0.0
Затем фильтруйте, где сумма compare
столбцов равна 1 :
df.loc[~df.compare1.add(df.compare2).eq(1)]
val compare1 compare2
0 a 0 0.0
1 b 0 NaN