Python 为虚拟变量创建一个模型

Python 为虚拟变量创建一个模型,python,r,dummy-variable,Python,R,Dummy Variable,从变量var1的训练数据集开始,如下所示: var1 A B C D 我想创建一个模型(我们称之为dummy\u model1),然后将训练数据集转换为: var1_A var1_B var1_C var1_D 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 此功能(或类似功能)存在于R中的dummies包和Pandas中的ge

从变量
var1
的训练数据集开始,如下所示:

var1
A
B
C
D
我想创建一个模型(我们称之为
dummy\u model1
),然后将训练数据集转换为:

var1_A  var1_B  var1_C  var1_D
1       0       0       0
0       1       0       0
0       0       1       0
0       0       0       1
此功能(或类似功能)存在于
R
中的
dummies
包和
Pandas
中的
get\u dummies
包中,甚至
SQL
中的
case
语句中

然后,我希望能够将
dummy_model1
应用于新的数据集:

var1
C
7
#
A
并获得以下输出:

var1_A  var1_B  var1_C  var1_D
0       0       1       0
0       0       0       0
0       0       0       0
1       0       0       0
我知道我可以在
SQL
中使用“case”语句来实现这一点,但如果我有大约2000个变量,我希望能够自动完成这一过程。此外,新数据集几乎总是有“坏”数据(例如,在上面的示例中,
7
#

有点不懂语言(只要是开源的),但更喜欢
Python
R
。请注意,数据超过500GB,因此限制了我的一些选择。提前谢谢

试试看:

# first set the variable to factor with levels specified
df$var1 <- factor(df$var1, levels = LETTERS[1:4])

model.matrix(data = df, ~var1-1)
#  var1A var1B var1C var1D
#1     0     0     1     0
#4     1     0     0     0

假设
var1
本身适合内存,下面是一个可能的解决方案:

首先,读入
var1

接下来,使用
get_dummies
将所有“培训”类别编码为虚拟变量。将列名存储为列表或数组

然后,读入培训数据集的前几行,以获取列名并将其存储为列表(或者,如果您已经知道这些,则可以跳过此步骤)

创建一个新的列表或数组,其中包含伪变量列名和相关的其他列(可以是数据集中除
var1
之外的每一列)。这将是最后一列编码

然后,读入测试数据。使用
get_dummies
对测试数据中的
var1
进行编码,知道它可能缺少类别或具有无关类别。然后重新索引数据以匹配最终的列编码

重新编制索引后,您将使用与培训一致的
var1
假人创建测试数据集

举例说明:

import pandas as pd
import numpy as np

training = pd.DataFrame({
        'var1': ['a','b','c'],
        'other_var':[4,7,3],
        'yet_another':[8,0,2]
    })

print training
   other_var var1  yet_another
0          4    a            8
1          7    b            0
2          3    c            2

test = pd.DataFrame({
        'var1': ['a','b','q'],
        'other_var':[9,4,2],
        'yet_another':[9,1,5]
    })

print test
   other_var var1  yet_another
0          9    a            9
1          4    b            1
2          2    q            5


var1_dummied = pd.get_dummies(training.var1, prefix='var1')
var_dummy_columns =  var1_dummied.columns.values

print var_dummy_columns
array(['var1_a', 'var1_b', 'var1_c'], dtype=object)

final_encoding_columns = np.append(training.drop(['var1'], axis = 1).columns, var_dummy_columns)

print final_encoding_columns
array(['other_var', 'yet_another', 'var1_a', 'var1_b', 'var1_c'], dtype=object)


test_encoded = pd.get_dummies(test, columns=['var1'])

print test_encoded
   other_var  yet_another  var1_a  var1_b  var1_q
0          9            9       1       0       0
1          4            1       0       1       0
2          2            5       0       0       1

test_encoded_reindexed = test_encoded.reindex(columns = final_encoding_columns, fill_value=0)

print test_encoded_reindexed
   other_var  yet_another  var1_a  var1_b  var1_c
0          9            9       1       0       0
1          4            1       0       1       0
2          2            5       0       0       0
这应该是您想要的,基于您的问题和评论中的预期输出


如果测试数据很容易放在内存中,您可以很容易地将其扩展到多个变量。只需为每个要编码的训练变量保存并迭代更新
final_encoding_columns
。然后在重新索引测试数据时,将所有这些列传递给
columns=
参数。使用完整的
final\u encoding\u列重新编制索引
,您应该已经全部设置好了。

在R中,您可以从了解
model.matrix
函数开始。您本质上是在问如何转换与您创建的伪变量编码一致的新数据(可能来自
get\u dummies
)从训练数据中?所以A和C被7编码,然后被忽略?如果是,我将发布一个简短的Python回答。如果“坏”数据是指“不同”的数据,而不是“代码破坏”的数据,那么这不是问题。我假设您的500gb数据集不适合内存(如果适合,请更正)。如果没有,请做一个信封背面的计算(或只是检查)如果您的单列
var1
适合内存。@FrankB。谢谢我现在有了一张更好的照片。我将把解决方案留给那些已经在写它们的人。明白了。然后我将在假设
var1
适合内存的情况下编写我的解决方案。我看到的两个(可能)问题是这个问题的数据大小问题(导入500GB+CSV),并且我不知道每个变量中有什么内容(文档不完整)。不必手动检查每个变量。即使我有文档说唯一的值是‘A’、‘B’和‘C’,也很可能是‘X’、‘Y’和‘Z’,谢谢Nick,很抱歉让您编写自定义代码。我希望有人已经把这个放进了一个包裹里,但是给你答案,我想他们没有。一点也不担心。当我将一个使用编码的分类变量的模型投入生产时,实际上经常会出现这种情况,因此我有一些易于访问的框架代码。
import pandas as pd
import numpy as np

training = pd.DataFrame({
        'var1': ['a','b','c'],
        'other_var':[4,7,3],
        'yet_another':[8,0,2]
    })

print training
   other_var var1  yet_another
0          4    a            8
1          7    b            0
2          3    c            2

test = pd.DataFrame({
        'var1': ['a','b','q'],
        'other_var':[9,4,2],
        'yet_another':[9,1,5]
    })

print test
   other_var var1  yet_another
0          9    a            9
1          4    b            1
2          2    q            5


var1_dummied = pd.get_dummies(training.var1, prefix='var1')
var_dummy_columns =  var1_dummied.columns.values

print var_dummy_columns
array(['var1_a', 'var1_b', 'var1_c'], dtype=object)

final_encoding_columns = np.append(training.drop(['var1'], axis = 1).columns, var_dummy_columns)

print final_encoding_columns
array(['other_var', 'yet_another', 'var1_a', 'var1_b', 'var1_c'], dtype=object)


test_encoded = pd.get_dummies(test, columns=['var1'])

print test_encoded
   other_var  yet_another  var1_a  var1_b  var1_q
0          9            9       1       0       0
1          4            1       0       1       0
2          2            5       0       0       1

test_encoded_reindexed = test_encoded.reindex(columns = final_encoding_columns, fill_value=0)

print test_encoded_reindexed
   other_var  yet_another  var1_a  var1_b  var1_c
0          9            9       1       0       0
1          4            1       0       1       0
2          2            5       0       0       0