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

#python #dataframe #vectorization

Вопрос:

У меня есть функция для установки цветов. В настоящее время я просматриваю фрейм данных и передаю функции одно значение, сопоставляю это значение с соответствующим значением цвета и возвращаю значение цвета. Теперь я хочу передать весь столбец из фрейма данных (вместо циклического просмотра фрейма данных) и вернуть массив значений цвета.

Вот упрощенная версия функции, которая в настоящее время работает, передавая одно значение (я просто задаю одно значение вместо того, чтобы показывать весь цикл через фрейм данных).:

     def set_LineQualityColor(LineQ):
      data = [['grey', 0], ['cornflowerblue', 1], ['lightgreen', 2],['seagreen', 3], 
            ['mistyrose', 4], ['lightcoral', 4.1],['rosybrown', 5], ['indianred', 5.1], 
            ['lightgray', 9]]
      df = pd.DataFrame(data, columns = ['CR', 'LineQuality'])   
      c=df[df['LineQuality']==LineQ]['CR'].values[0]
    return c
    
    LQ=4
    c= set_LineQualityColor(LQ)

 

Как я могу заставить это работать правильно, когда LineQ это столбец из фрейма данных? Т. Е.

 c= set_LineQualityColor(df.LQ)

 

Или есть более эффективный способ сделать это? Новичок в python. Спасибо.

Ответ №1:

Установите линейность в качестве индекса.

 data = [['grey', 0], ['cornflowerblue', 1], ['lightgreen', 2],['seagreen', 3], 
            ['mistyrose', 4], ['lightcoral', 4.1],['rosybrown', 5], ['indianred', 5.1], 
            ['lightgray', 9]]

df = pd.DataFrame(data, columns = ['CR', 'LineQuality'])
df.set_index(['LineQuality'], drop=True, inplace=True)
 

Что дает этот фрейм данных:

                          CR
LineQuality                
0.0                    grey
1.0          cornflowerblue
2.0              lightgreen
3.0                seagreen
4.0               mistyrose
4.1              lightcoral
5.0               rosybrown
5.1               indianred
9.0               lightgray
 

Затем выполните поиск с помощью loc .

 LQ_df = pd.DataFrame([1, 5, 4, 9, 4.1, 0, 4.0], columns=['LQ'])

LQ = LQ_df['LQ']

df.loc[LQ, 'CR']
 

Что дает эту серию:

 LineQuality
1.0    cornflowerblue
5.0         rosybrown
4.0         mistyrose
9.0         lightgray
4.1        lightcoral
0.0              grey
4.0         mistyrose
 

Нет смысла создавать фрейм df данных каждый раз при вызове функции, поэтому лучше создать его один раз перед вызовом функции. Затем вы можете определить функцию для использования df.loc , как мы делали это раньше:

 data = [['grey', 0], ['cornflowerblue', 1], ['lightgreen', 2],['seagreen', 3], 
            ['mistyrose', 4], ['lightcoral', 4.1],['rosybrown', 5], ['indianred', 5.1], 
            ['lightgray', 9]]

lineq_color_lookup = pd.DataFrame(data, columns = ['CR', 'LineQuality'])
lineq_color_lookup.set_index(['LineQuality'], drop=True, inplace=True)

def get_LineQualityColor(LineQ):
    return lineq_color_lookup.loc[LineQ, 'CR'] # .tolist() if you want it as a list
 

Я также изменил имя функции на get_LineQualityColor , потому что функция ничего не устанавливает-она возвращает только цвет, соответствующий заданной линейности.

Ответ №2:

Вы можете передать новый (или столбец) фрейм данных, чтобы объединить оба, чтобы получить результат.

 >>> def set_LineQualityColor_df(LineQ):
...     data = [['grey', 0], ['cornflowerblue', 1], ['lightgreen', 2],['seagreen', 3],
...             ['mistyrose', 4], ['lightcoral', 4.1],['rosybrown', 5], ['indianred', 5.1],
...             ['lightgray', 9]]
...     df = pd.DataFrame(data, columns = ['CR', 'LineQuality'])
...     #c=df[df['LineQuality']==LineQ]['CR'].values[0]
...     c = df.set_index('LineQuality').join(LineQ)
...     return c
...
>>> df_lineQ = pd.DataFrame({ 'LineQuality': [4,5]})
>>> set_LineQualityColor_df(df_lineQ).head(5)
                     CR  LineQuality
LineQuality
0.0                    grey          4.0
1.0          cornflowerblue          5.0
2.0              lightgreen          NaN
3.0                seagreen          NaN
4.0               mistyrose          NaN
 

Вы можете передать определенный столбец фрейма данных.

 >>> set_LineQualityColor_df(df_lineQ.LineQuality).head(5)
                         CR  LineQuality
LineQuality
0.0                    grey          4.0
1.0          cornflowerblue          5.0
2.0              lightgreen          NaN
3.0                seagreen          NaN
4.0               mistyrose          NaN
>>>