Python 缩放不规则多维数据帧

Python 缩放不规则多维数据帧,python,dataframe,scikit-learn,scale,Python,Dataframe,Scikit Learn,Scale,我有一个数据帧,如下例所示: import pandas as pd data = {'a1': [40, 0, 40, 100, 80], 'a2': [[0, 2], [4, 5], [10, 2], [3, 8], [0, 0]], 'a3': [[10, 2], [10, 0, 4], [1, 0, 1, 1], [-10, 6], [0, 2]], 'a4': [-1, -0.08, 0.4, 1, 0.2], } df

我有一个数据帧,如下例所示:

import pandas as pd
data = {'a1': [40, 0, 40, 100, 80],
        'a2': [[0, 2], [4, 5], [10, 2], [3, 8], [0, 0]],
        'a3': [[10, 2], [10, 0, 4], [1, 0, 1, 1], [-10, 6], [0, 2]],
        'a4': [-1, -0.08, 0.4, 1, 0.2],
        }
df = pd.DataFrame(data)
print(df)
    a1       a2            a3    a4
0   40   [0, 2]       [10, 2] -1.00
1    0   [4, 5]    [10, 0, 4] -0.08
2   40  [10, 2]  [1, 0, 1, 1]  0.40
3  100   [3, 8]      [-10, 6]  1.00
4   80   [0, 0]        [0, 2]  0.20
我想将其缩放到[0,1],并保存缩放器,以便将它们应用到另一个数据集上。
生成的数据帧应如下所示:

scaled_df
    a1          a2                       a3    a4
0  0.4    [0, 0.2]                 [1, 0.6]  0.00
1  0.0  [0.4, 0.5]            [1, 0.5, 0.7]  0.46
2  0.4    [1, 0.2]  [0.55, 0.5, 0.55, 0.55]  0.70
3  1.0  [0.3, 0.8]                 [0, 0.8]  1.00
4  0.8      [0, 0]               [0.5, 0.6]  0.60
对于没有嵌套列表的数据帧,我一直使用以下方法:

from sklearn.preprocessing import MinMaxScaler
df1 = df[['a1', 'a4']]
scaler = MinMaxScaler()
scaler.fit(df1)
scaled_df = scaler.transform(df1)
dump(scaler, open('scaler.pkl', 'wb'))

scaler = load(open('scaler.pkl', 'rb'))
scaled_df2 = scaler.transform(df2)
但是,这对嵌套列表的整个原始df不起作用。 我可以考虑一些“黑客”方法,比如对每一列,将其行连接在一个数组中,计算标量,将其存储在标量数组中,并将其应用于第二个数据帧,但我想知道是否有更好、更干净的方法来做到这一点。
有什么想法吗?

您可以浏览每个功能列,如果它们包含值列表,则将其展开为单独的列,然后将
MinMaxScaler
应用于展开的数据帧。因此,您可以坚持使用单个scaler对象

试试这个:

frames = []
for feature in df.columns:
    if df[feature].dtype != "object":
        frames.append(df[feature])
        continue
    tmp = pd.DataFrame(df[feature].to_list(), index=df.index)
    tmp.columns = [f"{feature}_{x}" for x in range(tmp.shape[1])]
    frames.append(tmp)
    
df_exploded = pd.concat(frames, axis=1)

sc = MinMaxScaler()
scaled_data = sc.fit_transform(df_expanded)
df_scaled = pd.DataFrame(scaled_data, columns=df_expanded.columns)
display(df_scaled)
结果:

    a1      a2_0    a2_1    a3_0    a3_1        a3_2    a3_3    a4
0   0.4     0.0     0.250   1.00    0.333333    NaN     NaN     0.00
1   0.0     0.4     0.625   1.00    0.000000    1.0     NaN     0.46
2   0.4     1.0     0.250   0.55    0.000000    0.0     0.0     0.70
3   1.0     0.3     1.000   0.00    1.000000    NaN     NaN     1.00
4   0.8     0.0     0.000   0.50    0.333333    NaN     NaN     0.60

理想情况下,您希望如何处理长度不同的列表元素?例如,如果第三行(索引2)没有对应的第四列值,您希望如何精确缩放
a3
?理想情况下,生成的数据帧应保持相同的形状(我在示例中添加了缩放的_df)。这是因为数据将被提供给不处理NaN的算法。