如何在具有包含numpy.ndarrays的列/列的pandas dataframe上执行StandardScaler?

3
我有一个带有 numpy.ndarrays 的列的 pandas dataframe:
  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数组以及其他所有内容标准化!

2个回答

2

StandardScaler期望每列都有数字值,但col2col4具有序列,因此出现错误。

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

目前,我假设对于给定列的所有行,序列中的元素数量相同,例如col_2的所有行都有3个值的数组。

由于StandardScaler分别计算每列的meanstd。对于序列列,有两种方法:

方法1:序列中所有位置的元素来自相同的分布。

在这种情况下,您应该获得所有值的meanstd。在对展平的数组进行StandardScaler拟合后,将其重新调整为原始形状。

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

在这种情况下,可以将单个列转换为2D numpy数组。您可以在该2D数组上适配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))



在第二种方法中,可以先将所有列堆叠起来,然后一次性对它们执行StandarScaler

谢谢您的回复!我准备开始实现这个,但是我注意到我的所有数字都不是numpy类型。我应该将数组中的所有数字和列中的整数转换为它们的numpy等效类型吗? - raceee
1
是的!我会推荐这样做。我正在编辑我的答案,将所有内容在缩放之前转换为浮点数! - Mohsin hasan

1
尝试将数组转换为数据框。我的理解是,它需要使用2-D数组而不是1-D数组进行操作。
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.]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接