самый эффективный способ установить индексацию столбцов фрейма данных для других столбцов

#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