Ошибка при использовании pandas при попытке получить данные столбца для category_subset - PullRequest
1 голос
/ 14 июля 2020

Я пытаюсь использовать инструменты Sklearn вместе с Pandas и np. Я пытаюсь запустить свой код (показан под ошибкой)

Traceback (most recent call last):
  File "C:/PycharmProjects/AISyiff/testingAi.py", line 129, in <module>
    categorical_subset = pd.get_dummies(categorical_subset[categorical_subset.columns.drop("protocol")])
  File "C:\PycharmProjects\AISyiff\venv\lib\site-packages\pandas\core\indexes\base.py", line 5018, in drop
    raise KeyError(f"{labels[mask]} not found in axis")
KeyError: "['protocol'] not found in axis"

Пожалуйста, дайте мне знать, где я допустил ошибку и что я могу сделать, чтобы исправить это!

import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn import preprocessing as preprocessing
from sklearn.metrics import accuracy_score
import matplotlib as mpl
mpl.use('TkAgg')
import seaborn as sns
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor

sns.set(style="white", context="talk")
mpl.rcParams['figure.dpi'] = 200
df = pd.read_csv("datasets_for_paper.csv", low_memory=False)

##firstPaint provides time info about page renderingso does ,rumSpeedIndex=avg page render
print(df.dtypes)
df["nodeId"] = df["nodeId"].astype(int)
df["numObj"] = df["numObj"].astype(int)
df["rumSpeedIndex"] = df['rumSpeedIndex'].astype(int)
df["pageLoadTime"] = df['pageLoadTime'].astype(int)
df["firstPaint"] = df['firstPaint'].astype(int)


# convert from name into pure string
def changeProtName(value):
    if value == 'H1s':
        return str('Hs')
    else:
        return str('Hl')


df['protocol'] = df['protocol'].map(lambda x: changeProtName(x))

# hot encode catagories as catagorical data
df['protocol'] = pd.Categorical(df["protocol"])
df['browser'] = pd.Categorical(df['browser'])
df['nodeType'] = pd.Categorical(df['nodeType'])
df['url'] = pd.Categorical(df['url'])


# list a bunch of details about categorical data
def summerize_data(df1):
    for column in df1.columns:
        print(column)
        if df.dtypes[column] == np.object:
            print(df1[column].value_counts())
        else:
            print(df1[column].describe())

        print('\n')


summerize_data(df)


def hotEncodingCats(df1):
    results = df1.copy()
    encoders = {}
    for column in results.columns:
        encoders[column] = preprocessing.LabelEncoder()
        results[column] = encoders[column].fit_transform(results[column])
    return results, encoders


print(df.dtypes)

encoded_data, _ = hotEncodingCats(df)
sns.heatmap(encoded_data.corr(), square=True)


encoded_data.tail(5)

encoded_data, encoders = hotEncodingCats(df)
new_series = encoded_data["protocol"]

X_train, X_test, y_train, y_test = train_test_split(encoded_data[encoded_data.columns.drop("protocol")], new_series,
                                                    train_size=0.70)
scaler = preprocessing.StandardScaler()

X_train = pd.DataFrame(scaler.fit_transform(X_train), columns=X_train.columns)
X_test = scaler.transform(X_test)

cls = linear_model.LogisticRegression()

cls.fit(X_train, y_train)
y_pred = cls.predict(X_test)

print(df.dtypes)
print(accuracy_score(y_test, y_pred))
print(df.dtypes)
print("cookieprint")

def mae(y_true, y_pred):
    return np.mean(abs(y_true - y_pred))

print("cookie3")

def fit_and_evaluate(model):
    # Train the model
    model.fit(X_train, y_train)

    # Make predictions and evalute
    model_pred = model.predict(X_test)
    model_mae = mae(y_test, model_pred)

    # Return the performance metric
    return model_mae


print(fit_and_evaluate(cls))
print("cookie1")
random_forest = RandomForestRegressor(random_state=60)
coefs = pd.Series(cls.coef_[0], index=X_train.columns)
print(X_train.columns)
print("cookie2")
coefs = coefs.sort_values()
plt.subplot(1, 1, 1)
plt.figure(figsize=(10,10))
coefs.plot(kind="bar", alpha=0.4)
plt.show()
print(coefs.sort_values(ascending=False))

features = df.copy()
numeric_subset = df.select_dtypes('number')
categorical_subset = df.select_dtypes('object')

categorical_subset = pd.get_dummies(categorical_subset[categorical_subset.columns.drop("protocol")])
features = pd.concat([numeric_subset, categorical_subset], axis = 1)
print(features.head())

1 Ответ

1 голос
/ 15 июля 2020

Мне удалось воспроизвести вашу проблему следующим образом:

>>> df = pd.DataFrame()
>>> df['protocol'] = pd.Categorical(['A', 'B', 'C', 'D', 'A'])
>>> df.select_dtypes('object')
Empty DataFrame
Columns: []

Вы можете видеть, что последняя строка, соответствующая

categorical_subset = df.select_dtypes('object')

, вероятно, возвращает пустой DataFrame ( если есть сомнения, было бы хорошо проверить, что categorical_subset действительно содержит то, что вы ожидали, что он будет содержать.

Это потому, что когда вы переназначили df['protocol'], который изначально содержал строки, pd.Categorical, его dtype (как и другие категориальные столбцы) больше не object, а category):

>>> df.dtypes
protocol    category
dtype: object

(этот вывод выглядит немного запутанным; в нем говорится, что dtype для protocol равен category, но под ним написано dtype: object: возвращаемое значение DataFrame.dtypes на самом деле является Series со столбцами для имени столбца и dtype, поэтому обманчивый dtype: object внизу относится к dtype этой серии).

Вероятно, это именно то, что вы действительно хотели:

>>> df.select_dtypes('category')
  protocol
0        A
1        B
2        C
3        D
4        A

На самом деле, в документации для select_dtypes:

Чтобы выбрать Pandas категориальные типы, используйте * 10 37 *

Вышеупомянутое является хорошим примером того, как создать минимальный воспроизводимый пример , а также в целом, как отлаживать небольшие программы. Сначала мы обратили внимание на проблемную область, строку

categorical_subset.columns.drop("protocol")

, где, по-видимому, не должно быть столбца с именем 'protocol'. Затем мы просто работаем в обратном направлении к тому, как был создан categorical_subset (мы вызвали df.select_dtypes('object') в нашем исходном фрейме данных). И кроме этого, все, что нам нужно, это пример фрейма данных с несколькими pd.Categorical столбцами.

...