Эффективное использование памяти для замены недопустимых значений в большом DataFrame?

1

Этот вопрос является продолжением следующего: как заменить определенные строки на общие значения столбцов в pandas DataFrame?

Скажем, у меня есть следующие панды DataFrame:

import pandas as pd

data = [['Alex',10],['Bob',12],['Clarke',13], ['Bob', '#'], ['Bob', '#'], ['Bob', '#'], ['Clarke', '#']]

df = pd.DataFrame(data,columns=['Name','Age'], dtype=float)

     Name Age
0    Alex  10
1     Bob  12
2  Clarke  13
3     Bob   #
4     Bob   #
5     Bob   #
6  Clarke   #

Строки 3-6 имеют недопустимые значения, строка #. Они должны быть заменены действительными значениями, выводящими:

     Name Age
0    Alex  10
1     Bob  12
2  Clarke  13
3     Bob  12
4     Bob  12
5     Bob  12
6  Clarke  13

Решения pandas, обсуждавшиеся для замены этих значений, обсуждались с использованием coerce или замены с помощью подмножества данных:

v = df.assign(Age=pd.to_numeric(df['Age'], errors='coerce')).dropna()
df['Age'] = df['Name'].map(v.set_index('Name').Age) 

или же

d= df[df['Age']!='#'].set_index('Name')['Age']
df['Age']=df['Name'].replace(d)

Проблема в том, что для pandas DataFrame с миллионами строк эти решения на основе панд становятся очень интенсивными в памяти.

В ситуациях, подобных этим с пандами, какое было бы наиболее практичное решение?

Я мог бы попытаться создать массивный словарь, используя df[df['Age']!='#'], С Name: Age в качестве пар ключ-значение. Затем, итерации через оригинальные панды DataFrame подряд за строкой; если есть строка с Age == #, то замените ее на основе пары ключ-значение в словаре. Недостатком этого является то, что for-loop будет навсегда.

Существуют ли другие решения, которые будут иметь лучшую производительность?

  • 0
    после d= df[df['Age']!='#'].set_index('Name')['Age'] сколько памяти потребляет d по сравнению с df ?
  • 0
    Пожалуйста, дайте мне знать, если вы пробовали это и все еще сталкиваетесь с проблемами?
Показать ещё 2 комментария
Теги:
pandas
dataframe
performance

1 ответ

1

Что делать, если вы попробуете что-то более эффективную с точки зрения памяти, например, вместо замены на основе словаря?

mapping = dict(df.drop_duplicates('Name', keep='first').values)
df['Age'] = df['Name'].map(mapping)

print(df)
     Name  Age
0    Alex   10
1     Bob   12
2  Clarke   13
3     Bob   12
4     Bob   12
5     Bob   12
6  Clarke   13

Другой альтернативой было бы использование списка:

mapping = dict(df.drop_duplicates('Name', keep='first').values)
df['Age'] = [mapping.get(x, np.nan) for x in df['Name']]

print(df)
     Name  Age
0    Alex   10
1     Bob   12
2  Clarke   13
3     Bob   12
4     Bob   12
5     Bob   12
6  Clarke   13

Это должно работать, если вначале должны быть действительные значения в "Возраст".

  • 0
    @ Jezrael да, я понимаю ... Я пытаюсь микрооптимизировать здесь. В моем первоначальном ответе (в другом посте) больше движущихся частей, потому что OP не беспокоился о производительности.
  • 0
    да, так можно как-нибудь измерить это? как memory_usage ?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню