добавление нового столбца pandas df на основе операций по строкам - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть такой фрейм данных:

Interesting           genre_1        probabilities
    1    no            Empty        0.251306
    2    yes           Empty        0.042043
    3     no          Alternative    5.871099
    4    yes         Alternative    5.723896
    5    no           Blues         0.027028
    6    yes          Blues         0.120248
    7    no          Children's     0.207213
    8    yes         Children's     0.426679
    9    no          Classical      0.306316
    10    yes         Classical      1.044135

Я бы хотел выполнить индекс GINI для той же категории на основе интересного столбца. После этого я хотел бы добавить такое значение в новый столбец pandas.

Это функция для получения индекса Джини:

#Gini Function
#a and b are the quantities of each class
def gini(a,b):
    a1 = (a/(a+b))**2
    b1 = (b/(a+b))**2
    return 1 - (a1 + b1) 

РЕДАКТИРОВАТЬ * К сожалению, у меня была ошибка в моем последнем желаемом кадре данных. Быть интересным или нет имеет значение, когда дело доходит до выбора prob (A) и prob (B), но оценка Джини будет одинаковой, потому что она будет измерять, сколько примесей мы получаем, чтобы классифицировать песню как интересную или нет. Таким образом, если вероятности составляют около 50/50%, то это будет означать, что показатель Джини достигнет максимума (0,5), и это потому, что одинаково возможно просто ошибиться, выбрав интересное или нет.

Итак, для первых двух строк индекс Джини будет:

a=no; b=Empty -> gini(0.251306, 0.042043)= 0.245559831601612
a=yes; b=Empty -> gini(0.042043, 0.251306)= 0.245559831601612

Тогда я бы хотел получить что-то вроде:

 Interesting           genre_1        percentages.  GINI INDEX
        1    no            Empty        0.251306         0.245559831601612
        2    yes           Empty        0.042043         0.245559831601612
        3     no          Alternative    5.871099         0.4999194135183881
        4    yes         Alternative    5.723896.     0.4999194135183881
        5    no           Blues         0.027028          ..
        6    yes          Blues         0.120248
        7    no          Children's     0.207213
        8    yes         Children's     0.426679
        9    no          Classical      0.306316          ..
        10    yes         Classical      1.044135         ..

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Хорошо, я думаю, что знаю, что вы имеете в виду. Приведенный ниже код не имеет значения, интересует ли значение «да» или «нет». Но то, что вы хотите, - это рассчитать коэффициент GINI двумя различными способами для каждой строки на основе значения в Интересном значении этой строки. Так что если интересно == нет, то результат 0,5, потому что a == b. Но если интересно «да», то вам нужно использовать a = вероятность [i] и b = вероятность [i + 1]. Поэтому пропустите этот раздел, чтобы получить обновленный код ниже.

import pandas as pd


df = pd.read_csv('df.txt',delim_whitespace=True)

probs = df['probabilities']


def ROLLING_GINI(probabilities):

    a1 = (probabilities[0]/(probabilities[0]+probabilities[0]))**2
    b1 = (probabilities[0]/(probabilities[0]+probabilities[0]))**2
    res = 1 - (a1 + b1)
    yield res

    for i in range(len(probabilities)-1):
        a1 = (probabilities[i]/(probabilities[i]+probabilities[i+1]))**2
        b1 = (probabilities[i+1]/(probabilities[i]+probabilities[i+1]))**2
        res = 1 - (a1 + b1)
        yield res


df['GINI'] = [val for val in ROLLING_GINI(probs)]

print(df)

Именно здесь начинаются настоящие проблемы, потому что, если я правильно понимаю вашу идею, вы не сможете рассчитать последнее значение GINI, потому что ваш фрейм данных не будет разрешить это. Важным моментом здесь является то, что последнее интересное значение в вашем фрейме данных - «да». Это означает, что я должен использовать a = вероятность [i] и b = вероятность [i + 1]. Но у вашего фрейма данных нет строки номер 11. У вас есть 10 строк, а в строке i == 10 вам понадобится вероятность в строке 11 для вычисления коэффициента GINI. Поэтому, чтобы ваша идея работала, последнее Интересное значение ДОЛЖНО быть «нет», в противном случае вы всегда получите ошибку индекса.

В любом случае, вот код:

import pandas as pd

df = pd.read_csv('df.txt',delim_whitespace=True)


def ROLLING_GINI(dataframe):

    probabilities = dataframe['probabilities']
    how_to_calculate = dataframe['Interesting']

    for i in range(len(dataframe)-1):

        if how_to_calculate[i] == 'yes':
            a1 = (probabilities[i]/(probabilities[i]+probabilities[i+1]))**2
            b1 = (probabilities[i+1]/(probabilities[i]+probabilities[i+1]))**2
            res = 1 - (a1 + b1)
            yield res

        elif how_to_calculate[i] == 'no':
            a1 = (probabilities[i]/(probabilities[i]+probabilities[i]))**2
            b1 = (probabilities[i]/(probabilities[i]+probabilities[i]))**2
            res = 1 - (a1 + b1)
            yield res


GINI = [val for val in ROLLING_GINI(df)]

print('All GINI coefficients: %s'%GINI)
print('Length of all calculatable GINI coefficients: %s'%len(GINI))
print('Number of rows in the dataframe: %s'%len(df))
print('The last Interesting value is: %s'%df.iloc[-1,0])

РЕДАКТИРОВАТЬ НОМЕР ТРИ (извините за позднюю реализацию):

Так что это работает, если я правильно применю индексацию. Проблема заключалась в том, что я хотел использовать вероятность Next , а не предыдущую. Так что это a = вероятности [i-1] и b = вероятности [i]

import pandas as pd

df = pd.read_csv('df.txt',delim_whitespace=True)


def ROLLING_GINI(dataframe):

    probabilities = dataframe['probabilities']
    how_to_calculate = dataframe['Interesting']

    for i in range(len(dataframe)):

        if how_to_calculate[i] == 'yes':
            a1 = (probabilities[i-1]/(probabilities[i-1]+probabilities[i]))**2
            b1 = (probabilities[i]/(probabilities[i-1]+probabilities[i]))**2
            res = 1 - (a1 + b1)
            yield res

        elif how_to_calculate[i] == 'no':
            a1 = (probabilities[i]/(probabilities[i]+probabilities[i]))**2
            b1 = (probabilities[i]/(probabilities[i]+probabilities[i]))**2
            res = 1 - (a1 + b1)
            yield res


GINI = [val for val in ROLLING_GINI(df)]

print('All GINI coefficients: %s'%GINI)
print('Length of all calculatable GINI coefficients: %s'%len(GINI))
print('Number of rows in the dataframe: %s'%len(df))
print('The last Interesting value is: %s'%df.iloc[-1,0])
1 голос
/ 11 февраля 2020

Я не уверен, как столбец Interesting влияет на все это, но я настоятельно рекомендую вам создать новый столбец, используя numpy.where(). Синтаксис будет выглядеть примерно так:

import numpy as np
df['GINI INDEX'] = np.where(__condition__,__what to do if true__,__what to do if false__)
...