Почему с pandas в python я не могу использовать переменную для изменения нескольких фреймов данных?

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

код предшественника, одинаковый для обоих:

 import pandas as pd

train = pd.read_csv('train.csv')
holdout = pd.read_csv('test.csv')

def process_age(df):
    df["Age"] = df["Age"].fillna(-0.5)
    cut_points = [-1,0,5,12,18,35,60,100]
    label_names = ["Missing","Infant","Child","Teenager","Young Adult","Adult","Senior"]
    df["Age_categories"] = pd.cut(df["Age"],cut_points,labels=label_names)
    return df

def create_dummies(df,column_name):
    dummies = pd.get_dummies(df[column_name],prefix=column_name)
    df = pd.concat([df,dummies],axis=1)
    return df

train = process_age(train)
holdout = process_age(holdout)
for x in ["Age_categories", "Pclass", "Sex"]:
    train = create_dummies(train, x)
    holdout = create_dummies(holdout, x)
  

«правильный» код:

 from sklearn.preprocessing import minmax_scale
# The holdout set has a missing value in the Fare column which
# we'll fill with the mean.
holdout["Fare"] = holdout["Fare"].fillna(train["Fare"].mean())

columns = ["SibSp","Parch","Fare"]

train['Embarked'] = train['Embarked'].fillna('S')
train = create_dummies(train,'Embarked')
holdout['Embarked'] = holdout['Embarked'].fillna('S')
holdout = create_dummies(holdout,'Embarked')
for y in columns:
    train[y   '_scaled']= minmax_scale(train[y])
    holdout[y   '_scaled']= minmax_scale(holdout[y])
  

Что я хочу сделать, это:

 from sklearn.preprocessing import minmax_scale
# The holdout set has a missing value in the Fare column which
# we'll fill with the mean.
holdout["Fare"] = holdout["Fare"].fillna(train["Fare"].mean())

columns = ["SibSp","Parch","Fare"]

for x in [train, holdout]:
    x['Embarked'] = x['Embarked'].fillna('S')
    x = create_dummies(x,'Embarked')
    for y in columns:
        x[y   '_scaled']= minmax_scale(x[y])
        x[y   '_scaled']= minmax_scale(x[y])
  

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

Ответ №1:

Прежде всего, имейте в виду, что если вы хотите получить доступ к элементам a и изменять list их с помощью a for , вы должны присвоить этот список переменной, иначе вы не сможете получить доступ к измененным элементам позже. Итак, сначала вам нужно что-то вроде этого:

 my_dataframes = [train, holdout]
  

Далее, при выполнении for циклов Python создает копии ваших итеративных элементов. Например, если вы запустите

 my_words = ['hello', 'my', 'friend']
for word in my_words:
    word=word.upper()
    print('Modification:', word)
print(my_words)
  

Ваш результат будет:

 Modification: HELLO
Modification: MY
Modification: FRIEND
['hello', 'my', 'friend']
  

Это происходит независимо от того, какие элементы вашего списка,, от строк до фреймов данных. Если вы хотите действительно изменить элементы своего списка, вы должны либо получить доступ к их индексу, либо создать новый список, добавив к нему измененные элементы.

Доступ к вашему индексу элементов

 my_dataframes = [train, holdout]
for i, df in enumerate(my_dataframes):
    df['Embarked'] = df['Embarked'].fillna('S')
    df = create_dummies(df,'Embarked')
    for y in columns:
        df[y   '_scaled']= minmax_scale(df[y])
        df[y   '_scaled']= minmax_scale(df[y])
    my_dataframes[i] = df
  

Выполнение этого кода даст вам нужные фреймы данных внутри исходного списка my_dataframes .

Создание нового списка

 my_dataframes = [train, holdout]
modified_dataframes = []

for df in my_dataframes:
    df['Embarked'] = df['Embarked'].fillna('S')
    df = create_dummies(df,'Embarked')
    for y in columns:
        df[y   '_scaled']= minmax_scale(df[y])
        df[y   '_scaled']= minmax_scale(df[y])
    modified_dataframes.append(df)
  

В этом случае вы сохраните исходные my_dataframes фреймы данных и получите новые modified_dataframes .

Надеюсь, это было полезно для вас. Дайте нам знать, если у вас возникнут дополнительные вопросы.