如何在包含 numpy.ndarrays 的列/列的 pandas 数据帧上执行 StandardScaler?

Posted

技术标签:

【中文标题】如何在包含 numpy.ndarrays 的列/列的 pandas 数据帧上执行 StandardScaler?【英文标题】:How to perform StandardScaler on pandas dataframe with a column/columns containing numpy.ndarrays? 【发布时间】:2019-12-14 15:10:26 【问题描述】:

我有一个 pandas 数据框,其中包含一些带有 numpy.ndarrays 的列:

  col1         col2           col3         col4
0  4    array([34, 56, 234])   7     array([765, 654])
1  3    array([11, 598, 1])    89    array([34, 90])

我想进行某种类型的缩放。

我已经完成了非常标准的事情:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)


from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

我遇到了非常预期的错误:

ValueError: setting an array element with a sequence.

我需要帮助标准化这些 numpy 数组以及其他所有内容!

【问题讨论】:

【参考方案1】:

StandardScaler 期望每一列都有 numeric 值,但 col2col4 有序列,因此会出现错误。

我认为最好单独处理带有序列的列,然后再与其余数据组合。

现在,我将假设所有行,不。给定列的元素顺序是相同的,例如col_2 的所有行都有 3 值数组。

因为,StandardScaler 会分别为所有列计算 meanstd。序列列有两种方法:

方法一:序列所有位置的元素都来自同一个分布。

在这种情况下,您应该得到meanstd 的所有值。将StandardScaler 拟合到扁平阵列后,将其重新整形为原始形状。

方法2:序列不同位置的元素来自不同的分布。

在这种情况下,可以将单个列转换为 2D numpy 数组。您可以将StandardScaler 放在该二维数组上(每列meanstd 将分别计算)并在转换后将其恢复为单列。

以下是两种方法的代码:

# numeric columns should work as expected
X_train_1 = X_train[['col1', 'col3']]
X_test_1 = X_test[['col1', 'col3']]

sc = StandardScaler()
X_train_1 = sc.fit_transform(X_train_1)
X_test_1 = sc.transform(X_test_1)

# first convert seq column to a 2d array
X_train_col2 = np.vstack(X_train['col2'].values).astype(float)
X_test_col2 = np.vstack(X_test['col2'].values).astype(float)

# for sequence columns, there are two approaches:
# Approach 1
sc_col2 = StandardScaler()
X_train_2 = sc_col2.fit_transform(X_train_col2.flatten().reshape(-1, 1))
X_train_2 = X_train_2.reshape(X_train_col2.shape)

X_test_2 = sc_col2.transform(X_test_col2.flatten().reshape(-1, 1))
X_test_2 = X_test_2.reshape(X_test_col2.shape)


# Approach 2
sc_col2 = StandardScaler()
X_train_2 = sc_col2.fit_transform(X_train_col2)

X_test_2 = sc_col2.transform(X_test_col2)

# To assign back to dataframe, you can do following:
X_test["col2_scaled"] = X_test_2.tolist()

# To stack with other numpy arrays
X_train_scaled = np.hstack((X_train_1, X_train_2))


在方法 2 中,可以先堆叠所有列,然后一次性对所有列执行StandarScaler

【讨论】:

感谢您的回复!我即将准备好实现这一点,但我注意到我所有的数字都不是 numpy 类型。我应该将数组中的所有这些数字和列中的整数转换为它们的 numpy 等效类型吗? 是的!我会建议这样做。我正在编辑我的答案以在缩放之前将所有内容转换为浮动!【参考方案2】:

尝试将数组转换为数据框。我有限的理解是它需要使用二维数组而不是一维数组。

import pandas as pd
import numpy as np    

X = pd.DataFrame(np.array(([34, 56, 234]))
y = pd.DataFrame(np.array([11, 598, 1]))

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)


from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

X_train
Out[38]: 
array([[ 1.],
       [-1.]])

【讨论】:

以上是关于如何在包含 numpy.ndarrays 的列/列的 pandas 数据帧上执行 StandardScaler?的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 pandas 系列、numpy ndarrays 或简单的 python 字典?

JSON - 使用 numpy 数组条目序列化 pandas 数据帧

Python:打印 Pandas 数据框返回 numpy.ndarray 属性错误

如何在报告中创建一个包含所有已检查列名称的列?

如何在 Apache Pig 中查找包含大量单词的列是不是具有真实的电子邮件 ID?

如何在 Spark 中对包含日期和时间值的列进行排序?