#pandas #performance #dataframe #indexing #eval
#pandas #Производительность #фрейм данных #индексирование #оценка
Вопрос:
У меня большой фрейм данных. Один из моих столбцов содержит имена других. Я хочу оценить этот столбец и установить в каждой строке значение ссылочного столбца:
|A|B|C|Column|
|:|:|:|:-----|
|1|3|4| B |
|2|5|3| A |
|3|5|9| C |
Желаемый результат:
|A|B|C|Column|
|:|:|:|:-----|
|1|3|4| 3 |
|2|5|3| 2 |
|3|5|9| 9 |
Я добиваюсь этого результата, используя:
df.apply(lambda d: eval("d." d['Column']), axis=1)
Но это очень медленно, даже при использовании swifter. Есть ли более эффективный способ выполнить это?
Ответ №1:
Для повышения производительности используйте df.to_numpy()
:
In [365]: df['Column'] = df.to_numpy()[df.index, df.columns.get_indexer(df.Column)]
In [366]: df
Out[366]:
A B C Column
0 1 3 4 3
1 2 5 3 2
2 3 5 9 9
Комментарии:
1. Этот метод без .to_numpy() выполняется на порядок быстрее. Есть какие-либо подсказки о том, почему это происходит?
2. Что вы подразумеваете под без to_numpy?
3. df[‘Column’] = df.to_numpy()[df.index, df.columns.get_indexer(df.Column)] против df[‘Column’] = df[‘Column’].значения[df.index, df.columns.get_indexer(df.Column)]
4. Я имел в виду: vs df[‘Column’] = df.values[df.index, df.columns.get_indexer(df.Column)]
Ответ №2:
Для Pandas < 1.2.0 используйте lookup
:
df['Column'] = df.lookup(df.index, df['Column'])
From 1.2.0
, lookup
не рекомендуется, вы можете просто использовать for
цикл:
df['Column'] = [df.at[idx, r['Column']] for idx, r in df.iterrows()]
Вывод:
A B C Column
0 1 3 4 3
1 2 5 3 2
2 3 5 9 9
Ответ №3:
Поскольку lookup
будет numpy
рекомендован метод try с get_indexer
df['new'] = df.values[df.index,df.columns.get_indexer(df.Column)]
df
Out[75]:
A B C Column new
0 1 3 4 B 3
1 2 5 3 A 2
2 3 5 9 C 9