为虚拟变量创建模型
Create a Model for Dummy Variables
从变量 var1
的训练数据集开始:
var1
A
B
C
D
我想创建一个模型(我们称之为 dummy_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_dummies
包中,甚至存在于 case
中SQL
中的语句。
然后我希望能够将 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' 语句执行此操作,但如果我有大约 2,000 个变量,我很乐意自动执行该过程。此外,新数据集几乎总是有 "bad" 数据(例如,上例中的 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
# or even
sapply(LETTERS[1:4], function(x) as.numeric(x==df$var1))
# A B C D
#[1,] 0 0 1 0
#[2,] 0 0 0 0
#[3,] 0 0 0 0
#[4,] 1 0 0 0
假设 var1
适合自己的内存,这是一个可能的解决方案:
首先,读入var1
。
接下来,使用 get_dummies
将所有 "training" 类别编码为虚拟变量。将列名称存储为列表或数组。
然后,读取训练数据集的前几行以获取列名并将它们存储为列表(或者如果您已经知道这些,则可以跳过此步骤)。
创建一个包含虚拟变量列名称和相关其他列的新列表或数组(这可能只是数据集中除 var1
之外的每一列)。这将是最后的列编码。
然后,读入你的测试数据。使用 get_dummies
对测试数据中的 var1
进行编码,知道它可能缺少类别或具有无关类别。然后重新索引数据以匹配最终列编码。
重建索引后,您将得到一个测试数据集,其中包含 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_encoding_columns
重新索引,您应该已经准备就绪。
从变量 var1
的训练数据集开始:
var1
A
B
C
D
我想创建一个模型(我们称之为 dummy_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_dummies
包中,甚至存在于 case
中SQL
中的语句。
然后我希望能够将 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' 语句执行此操作,但如果我有大约 2,000 个变量,我很乐意自动执行该过程。此外,新数据集几乎总是有 "bad" 数据(例如,上例中的 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
# or even
sapply(LETTERS[1:4], function(x) as.numeric(x==df$var1))
# A B C D
#[1,] 0 0 1 0
#[2,] 0 0 0 0
#[3,] 0 0 0 0
#[4,] 1 0 0 0
假设 var1
适合自己的内存,这是一个可能的解决方案:
首先,读入var1
。
接下来,使用 get_dummies
将所有 "training" 类别编码为虚拟变量。将列名称存储为列表或数组。
然后,读取训练数据集的前几行以获取列名并将它们存储为列表(或者如果您已经知道这些,则可以跳过此步骤)。
创建一个包含虚拟变量列名称和相关其他列的新列表或数组(这可能只是数据集中除 var1
之外的每一列)。这将是最后的列编码。
然后,读入你的测试数据。使用 get_dummies
对测试数据中的 var1
进行编码,知道它可能缺少类别或具有无关类别。然后重新索引数据以匹配最终列编码。
重建索引后,您将得到一个测试数据集,其中包含 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_encoding_columns
重新索引,您应该已经准备就绪。