Function 数据帧的列正在被交换:当我按名称标识和分配列时,为什么我的循环要切换列值?

Function 数据帧的列正在被交换:当我按名称标识和分配列时,为什么我的循环要切换列值?,function,dataframe,for-loop,scikit-learn,imputation,Function,Dataframe,For Loop,Scikit Learn,Imputation,我需要帮助与具体的代码,我将粘贴在下面。我使用的是迪安·德科克收集的艾姆斯住房数据集。 我正在使用Python笔记本并通过Anaconda的Jupyter Lab 2.1.5进行编辑。 下面的代码应该替换所有np.nan或“无”值。出于某种原因, 在for循环中反复调用手工制作的函数后,生成的数据帧的列将被交换 注:我知道我可以用“插补器”来完成这项工作。我计划选择数字和对象类型特征,分别插补它们,然后将它们放回一起。作为旁注,在使用文本显示或以其他方式验证手动输出的详细信息时,是否有任何方法可

我需要帮助与具体的代码,我将粘贴在下面。我使用的是迪安·德科克收集的艾姆斯住房数据集。 我正在使用Python笔记本并通过Anaconda的Jupyter Lab 2.1.5进行编辑。 下面的代码应该替换所有
np.nan
或“无”值。出于某种原因, 在for循环中反复调用手工制作的函数后,生成的数据帧的列将被交换

注:我知道我可以用“插补器”来完成这项工作。我计划选择数字和对象类型特征,分别插补它们,然后将它们放回一起。作为旁注,在使用文本显示或以其他方式验证手动输出的详细信息时,是否有任何方法可以做到这一点

在相关单元格中,流程为:

  • 获取并分配数据帧中数据点的数量
    df\u train
  • 获取并分配一个序列,该序列列出
    df\u列中的空值计数。语法是
    sr\u null\u counts=df\u train.isnull().sum()
  • 创建一个空列表,其中附加了5%值等于null的要素名称。它们将在稍后被丢弃, 在for循环之外。我起初认为这是问题所在,因为命令将
    df\u train
    的列放置到位 以前在for循环中
  • 重复调用手工函数,为
    df_train
    输入空值不超过行计数5%的列
  • 我使用了一个具有for循环和嵌套try-except语句的函数来:

  • 当序列是数据帧中的列时,接受序列和(可选)序列的名称。它指定传递序列的副本 一个局部变量
  • 按照准确的顺序,(a)尝试用传递序列的平均值替换所有空(
    NaN
    None
    )值。 (b) 如果失败,尝试用序列的中值替换所有空值。 (c) 如果即使失败,也用序列的模式替换所有空值
  • 返回序列的已编辑副本,并替换所有空值。它还应该打印出字符串,告诉我什么功能 已修改,使用什么汇总统计数据替换/插补缺失值
  • 最后一行是删除所有标记为缺失值超过5%的列

    以下是完整的代码:

    将主数据帧拆分为一个序列和测试集。 通过
    df\u housing=pd.read\u csv(sep='\t',filepath\u或\u buffer=“AmesHousing.tsv”)加载完整的数据集。

    def make_traintest(df, train_fraction = 0.7, random_state_val = 88):
        df = df.copy()
        df_train = df.sample(frac = train_fraction, random_state = random_state_val)    
        bmask_istrain = df.index.isin(df_train.index.values)
        df_test = df.loc[ ~bmask_istrain ]
        
        return {
            "train":df_train,
            "test":df_test
            }
    
    dict_traintest = make_traintest(df = df_housing)
    df_train = dict_traintest["train"]
    df_test = dict_traintest["test"]
    
    获取具有空值的列的列表 手工功能的定义: For循环 获取null值的计数,定义要删除以允许追加的空列列表,并重复执行 执行以下操作:对于
    lst\u have\u nulls
    中的每一列,检查该列是否有相等、小于或大于5%的缺失值。 如果更多,请将该列附加到
    lst\u drop
    。否则,调用手工输入函数。在for循环之后,将所有列放入
    lst\u下降
    ,到位

    我哪里出错了?如果你需要整个笔记本,我已经上传到Kaggle了。这里有一个链接。

    更新:在使用更改测试Anvar的答案后,问题仍然存在 当我尝试Anvar Kurmukov的代码时,我的数据帧列值仍然被交换。我所做的更改是在要检查的数据类型列表中添加
    int
    float
    。更改位于for循环内:
    如果数据输入[np.int64,np.float64,int,float]

    在完整的笔记本中,我的另一部分代码可能有问题。我需要通过从顶部逐单元调用
    df_train.info()
    来检查它在哪里。我在公开的笔记本上测试了代码。在128号牢房。出于某种原因,在运行Anvar的代码后,
    df\u train.info()
    方法返回以下内容:

        1st Flr SF  2nd Flr SF  3Ssn Porch  Alley   Bedroom AbvGr   Bldg Type   Bsmt Cond   Bsmt Exposure   Bsmt Full Bath  Bsmt Half Bath  ... Roof Style  SalePrice   Screen Porch    Street  TotRms AbvGrd   Total Bsmt SF   Utilities   Wood Deck SF    Year Built  Year Remod/Add
    1222    1223    534453140   70  RL  50.0    4882    Pave    NaN IR1 Bnk ... 0   0   0   0   0   NaN NaN NaN 0   87000
    1642    1643    527256040   20  RL  81.0    13870   Pave    NaN IR1 HLS ... 52  0   0   174 0   NaN NaN NaN 0   455000
    1408    1409    905427050   50  RL  66.0    21780   Pave    NaN Reg Lvl ... 36  0   0   144 0   NaN NaN NaN 0   185000
    1729    1730    528218050   60  RL  65.0    10237   Pave    NaN Reg Lvl ... 72  0   0   0   0   NaN NaN NaN 0   178900
    1069    1070    528180110   120 RL  58.0    10110   Pave    NaN IR1 Lvl ... 48  0   0   0   0   NaN NaN NaN 0   336860
    

    tl;dr而不是
    尝试:除了
    之外,您只需使用
    if
    并检查列的数据类型;您不需要迭代列

    drop_columns = df.columns[df.isna().sum() / df.shape[0] > 0.05]
    df.drop(drop_columns, axis=1)
    
    num_columns = []
    cat_columns = []
    
    for col, dtype in df.dtypes.iteritems():
        if dtype in [np.int64, np.float64]:
            num_columns.append(col)
        else:
            cat_columns.append(col)
            
    df[num_columns] = df[num_columns].fillna(df[num_columns].mean())
    df[cat_columns] = df[cat_columns].fillna(df[cat_columns].mode())
    
    make\u traintest
    函数的简短评论:我只需返回两个单独的数据帧,而不是字典,或者使用
    sklearn.model\u selection.train\u test\u split

    upd。您可以在一列中检查NaN值的数量,但如果您的唯一目标是插补NaN,则无需检查。

    答案 我发现了为什么我的列被交换的答案。他们实际上并没有被交换。最初的问题是我没有将“Order”列设置为索引列。为了解决电脑笔记本上的问题,我只需将以下参数和值添加到
    pd.read\u csv
    index\u col=“Order”
    。这解决了我本地笔记本上的问题。然而,当我在Kaggle笔记本上试用时,它并没有解决问题

    出于某种原因,我第一次在笔记本上使用的艾姆斯住房数据集的版本也是导致列交换的原因。

    def make_traintest(df, train_fraction = 0.7, random_state_val = 88):
        df = df.copy()
        df_train = df.sample(frac = train_fraction, random_state = random_state_val)    
        bmask_istrain = df.index.isin(df_train.index.values)
        df_test = df.loc[ ~bmask_istrain ]
        
        return {
            "train":df_train,
            "test":df_test
            }
    
    dict_traintest = make_traintest(df = df_housing)
    df_train = dict_traintest["train"]
    df_test = dict_traintest["test"]
    
    Anvar的代码很好。您可以测试我编写的代码,但为了安全起见,请遵循Anvar的代码。我的仍有待测试

    测试完成 我修改了我在问题中链接的Kaggle笔记本。我使用了我在电脑上实际使用的数据集。当我这样做时,Anvar Kurmukov的答案给出的代码非常有效。我测试了自己的代码,看起来不错,但在尝试之前测试两个版本。我只使用
    head()
    查看了数据集,并手动检查了列输入。如果您想查看笔记本,请查看以下内容:

    为了测试数据集是否有故障,我创建了数据帧。一个是直接从上传到Kaggle的本地文件中获取的。另一个使用我使用的艾姆斯爱荷华州住房数据集的当前版本作为输入。这些柱子与柱子正确地“对齐”
    drop_columns = df.columns[df.isna().sum() / df.shape[0] > 0.05]
    df.drop(drop_columns, axis=1)
    
    num_columns = []
    cat_columns = []
    
    for col, dtype in df.dtypes.iteritems():
        if dtype in [np.int64, np.float64]:
            num_columns.append(col)
        else:
            cat_columns.append(col)
            
    df[num_columns] = df[num_columns].fillna(df[num_columns].mean())
    df[cat_columns] = df[cat_columns].fillna(df[cat_columns].mode())