Динамическое назначение столбцов в Панд Python

#python #pandas #lambda #iteration #list-comprehension

Вопрос:

У меня есть фрейм данных pandas, из которого я хотел бы создать несколько столбцов функций, связанных с текстом. У меня также есть класс, который вычисляет эти функции. Вот мой код:

 r = ReadabilityMetrics() text_features = [['sentence_count', r.sentence_count], ['word_count', r.word_count], ['syllable_count', r.syllable_count], ['unique_words', r.unique_words],  ['reading_time', r.reading_time], ['speaking_time', r.speaking_time], ['flesch_reading_ease', r.flesch_reading_ease], ['flesch_kincaid_grade', r.flesch_kincaid_grade],   ['char_count', r.char_count]]  (df  .assign(**{t:df['description'].apply(f) for t, f in text_features}) )  

Я повторяю text_features , чтобы динамически создавать столбцы.

Мой вопрос: как я могу удалить ссылки на методы и сделать text_features их более краткими?

Например, я хотел бы иметь text_features = ['sentence_count', 'word_count', 'syllable_count', ...] , и поскольку имена столбцов совпадают с именами функций, динамически ссылаться на функции. Наличие вложенного списка не кажется сухим, поэтому ищите более эффективную реализацию.

Ответ №1:

Я думаю, что вы ищете это:

 text_features = ['sentence_count', 'word_count', 'syllable_count', 'unique_words', 'reading_time', 'speaking_time', 'flesch_reading_ease', 'flesch_kincaid_grade', 'char_count']  df.assign(**{func_name: df['description'].apply(getattr(r, func_name)) for func_name in text_features})  

Ответ №2:

 for column_name, function in text_features:  df[column_name] = df['description'].apply(function)  

Я думаю, что это нормально. Я бы, вероятно, определил text_features как список кортежей, а не список списков.

Если вы уверены, что он должен быть более кратким, определите text_features его как список строк.

 for column name in text_features:  df[column_name] = df['description'].apply(getattr(r, column_name))  

Я бы не стал пытаться сделать его более кратким (например, использовать ** с помощью диктанта), чтобы сделать решение менее эзотеричным, но это всего лишь вопрос мнения.

Ответ №3:

В вашем случае попробуйте getattr

 (df  .assign(**{t:df['description'].apply(getattr(r, t)()) for t in text_features}) )