【问题标题】:Convert Pandas Dataframe with mixed datatypes to LibSVM format将混合数据类型的 Pandas Dataframe 转换为 LibSVM 格式
【发布时间】:2020-08-11 15:01:23
【问题描述】:

我有一个大约百万行和 3 列的 pandas 数据框。这些列有 3 种不同的数据类型。 NumberOfFollowers 是数值数据类型,UserName 是分类数据类型,Embeddings 是分类集合类型。

df:

Index  NumberOfFollowers                  UserName                    Embeddings        Target Variable

0        15                                name1                      [0.5 0.3 0.2]       0
1        4                                 name2                      [0.4 0.2 0.4]       1
2        8                                 name3                      [0.5 0.5 0.0]       0
3        10                                name1                      [0.1 0.0 0.9]       0
...      ...                               ....                       ...                 ..

我想将此 pandas 数据帧转换为 LibSVM 输入格式。

期望的输出:

0 0:15 4:1 1:0.5 2:0.3 3:0.2
1 0:4 5:1 1:0.4 2:0.2 3:0.4
0 0:8 6:1 1:0.5 2:0.5 3:0.0
0 0:10 4:1 1:0.1 2:0.0 3:0.9
...

我发现的一个解决方案是:

https://scikit-learn.org/stable/modules/generated/sklearn.datasets.dump_svmlight_file.html

它将输入作为 NumPy 数组或稀疏矩阵。

UserName 具有一百万个唯一值,因此在此列上调用 pd.get_dummies 并将其存储为密集的 NumPy 数组不是解决方案,并且不适合内存。

所以,我知道它可以使用稀疏矩阵来完成,但是,我不知道如何将上述混合数据类型的数据转换为稀疏矩阵,然后使用 sklearn.datasets.dump_svmlight_file.html。

实际上,我有很多混合数据类型的列,我需要将它们转换为 libSVM 格式。但是,所有列都属于上述三种类型之一。

提前感谢您对如何解决上述问题的任何想法。

【问题讨论】:

    标签: pandas scikit-learn sparse-matrix libsvm


    【解决方案1】:

    我自己编写了这个函数。它有效,但是真的很慢。欢迎任何更快的解决方案。

    def construct_line(row, columns, dtypes, string_dict, file_obj, index, time1):
    
        if index % 1000000 == 0:
                print(str(time.time() - time1) +": "+ str(index))
    
        global categorical_index
        numerical_index = 0
        new_line = str(row[-1])+ " "
        for i in range(len(columns) - 1):
                value_at_i = row[i]
                dtype_at_i = dtypes[i]
                column_name_at_i = columns[i]
    
                if ((dtype_at_i == object) or (dtype_at_i == bool)): # Categorical Features
                        if (dtype_at_i == bool):
                                value_at_i =  bool_to_str(value_at_i)
    
                        value_to_be_found = column_name_at_i +"_"+ value_at_i
    
                        if value_to_be_found in string_dict:
                                indexed_value = string_dict[value_to_be_found]
                                new_line = new_line + str(indexed_value)+":1 "
    
                        else:
                                indexed_value = categorical_index
                                categorical_index = categorical_index + 1
                                new_line = new_line + str(indexed_value)+":1 "
                                string_dict[value_to_be_found] = indexed_value
    
                else: # Numerical Features
                        new_line = new_line + str(numerical_index) + ":" +str(value_at_i)+" "
                        numerical_index = numerical_index + 1
        file_obj.write(new_line+"\n")
    
    cnames_numerical = list(train_df.select_dtypes(exclude=['object', 'bool']).columns)
    categorical_index = len(cnames_numerical) - 1 # Categorical indices start from here.
    string_dict = {}
    f_train_df = open("train_df.csv", 'a')
    print(len(train_df))
    time1 = time.time()
    train_df.apply(lambda x : construct_line(x, train_df.columns, train_df.dtypes, string_dict, f_train_df, x.name,\
                                             time1), axis = 1)
    f_train_df.close()
    print(len(test_df))
    f_test_df = open("test_df.csv", 'a')
    test_df.apply(lambda x : construct_line(x, test_df.columns, test_df.dtypes, string_dict, f_test_df, x.name,\
                                           time1), axis = 1)
    f_test_df.close()
    

    【讨论】:

      猜你喜欢
      • 2019-11-17
      • 1970-01-01
      • 2017-03-19
      • 2017-10-10
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 2017-02-13
      • 2012-07-24
      相关资源
      最近更新 更多